diff options
author | Tor Norbye <tnorbye@google.com> | 2014-07-25 12:24:15 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2014-07-25 12:24:21 -0700 |
commit | 2e5965e996aad62ab1338b09d54caaf99ff3dd6a (patch) | |
tree | 68aa5081765150003d05155215812e629de09ec8 /platform/platform-impl/src/com | |
parent | 65f60eb9011bb2c549a6d83ae31257480368ddc5 (diff) | |
download | idea-2e5965e996aad62ab1338b09d54caaf99ff3dd6a.tar.gz |
Snapshot idea/138.1283 from git://git.jetbrains.org/idea/community.git
047cbb9: IDEA-127620 - Clouds: move frameworks to the top level in new module/project wizard - refactoring of import
1d1914f: IDEA-127620 - Clouds: move frameworks to the top level in new module/project wizard - remove from JavaEE group
3206e15: Merge remote-tracking branch 'origin/master'
a513e70: enable injected context for actions in action popups (IDEA-126995)
70c5d69: CommentInjector: improved detection and IDEA-114915 InjectorUtils performance
482cdc2: @MagicConstant added
997dc0b: do not show VM names in run configurations: junit, application (IDEA-126880)
9873768: merge commands to replace duplicates (IDEA-126776)
e9a17df: field can be local: when field is used in method for read it can't be converted to local if used in another methods (IDEA-127159)
f9e6f06: faster LexerEditorHighlighter.checkContentIsEqualTo
6051f49: generic debugger settings: step 3 — root settings (Debugger node content) — Java transformed
bcb94d7: cleanup
a12ac6c: treat Diagnostic.Kind.NOTE as information message, not a warning message (IDEA-105383)
f367dcb: IDEA-127666 Add tooltip to "Project Setting" icon
08d9677: add delegate method to TextFieldWithHistoryWitBrowseButton
ce0d23f: change messages for postfix templates configurable
d7d7e88: platform: syntax compatibility with antiquated Python versions for environment loader
2a10168: SwingHelper moved to platform-impl
0299b30: auto-import context variable declaration type when completing (IDEA-90157)
e353c2f: prefer some well-known java util classes in completion (IDEA-100669)
f81e96e: java chained completion: qualifier class items shouldn't be inserted as constructors
7cb41f8: Update image to visualize the project-based configurable in the Settings dialog.
e1d651b: Cleanup (formatting)
a7e55c6: time limit for constant search
9cce5c7: do not split annotations on multiple lines for params (IDEA-127017)
0aa3890: simplified, added filtering for subsequent parameter pairs: "key, value", "first, second"
d477f91: IDEA-59662: Provide ability to specify right margin (columns) for each file type separately (enabled for PHP)
9b820f7: IDEA-127679 ArrayIndexOutOfBoundsException if no default or focused button is specified
4c997e0: Prevent NPE in AbstractPopup and add corresponding logging
5a49a15: fix inset: VerticalFlowLayout incorrectly uses vertical gap as top inset
ece44da: cleanup
5a46a42: generic debugger settings: step 3 — root settings (Debugger node content)
04518cd: Inspections settings ui: tools not initialized if no necessity to apply inspections filter
da81c5d: ProjectFileIndex#isIgnored renamed to 'isExcluded'
0e67032: Return accidentally removed PyStringLiteralFixer
3089c9c: PY-12877 Complete statement doesn't insert colon for 'with' statement
1c70a28: IG inline fixes: use inline method processor; if simple getter is inlined in simple expr statement - it should be deleted (IDEA-127135)
8835827: logging for (IDEA-127288)
b585c95: inline method: check unique names for this variable in initial class scope (IDEA-127411)
ccc235e: tests: show warning when only ignored tests were detected (IDEA-127660)
ad42de6: vcs: reformat and cleanup
e9fe369: fixed starting jps-builders tests
9d121c2: fix disposeUIResources if merged
2e780d7: turn off contract inference for overrideable methods: fix logic
1bf7333: don't measure MinusculeMatcher performance
2eae3c8: contract inference: take explicit parameter notnull into account (IDEA-127667)
8851417: non-code gutter: get annotations for bytecode psi when highlighting library source
6608b52: generic debugger settings: step 2 — stepping — transform Groovy, all Stepping configurable on one page
e46729f: cleanup
dd0fd0f: ContainerUtil notNullize/nullize
3d30b27: extract EMPTY_SETTINGS_PANEL_PROVIDER
efe0d5a: Inspections settings ui: filter actions in toolbar added
006705c: DefaultVcsRootPolicy refactoring: 'isIgnored' check moved from 'matchesDefaultMapping' implementations to 'getMappingFor'
363b2cd: simplification
12a3d4f: platform: minor optimization (do not rename/delete directory recursively)
9a80d33: vfs: on create/delete notifications mark a child dirty as well
74d6cb2: diff: use separate action for 'roolback' for file (VCS action) and 'roolback' for local changes (LST action)
8b69a0f: diff: fix access to the invalid ranges
1f4de9d: diff: diff from LineStatusTracker
950a80a: IDEA-110611 diff: Ability to revert lines in selection
b6cd05a: diff: small fixes in LineStatusTracker
db873ee: Use Guava's immutable lists instead of static initializers in PySmartEnterProcessor
b1b8116: PY-9176 Converting % to format() doesn't handle multiline string literals
3d377d9: trigger automake for deleted files
1101b55: Merge remote-tracking branch 'origin/master'
3bf8f90: fix paint track
1e1a9c7: IDEA-61550 respect EditorFilter
831cecb: Merge remote-tracking branch 'origin/master'
28dd985: make editor vertical scrollbar bg the same as editor bg on Mac
c3a963a: fix preferred height for JComboBox too
da026c5: override ControlDoubleClick+Left/Right, make new bindings switchable
222d8ef: bind 'clone caret' actions to ControlDoubleClick+Up/Down
41034f6: DirectoryInfo: extracted sub-class
693b2a2: DirectoryIndexTest: renames
a06bd87: Inspections settings ui: added mask and fixed height of severity icon
73dfd94: parameter name folding reducing: - do not inline if parameter length is less than 3 - do not inline if two subsequent parameters has interval names (beginIndex, endIndex; startId, endId; from, to...)
90d58be: DirectoryIndex: removed unnecessary isProjectExcludeRoot method
359bc94: DirectoryInfo simplification: use booleans instead of bit flags because now we have no so many instance of this class (CR-IC-5807)
df51a0d: Inspections settings ui: severity colors in tree showed only for enabled inspections
931d600: Inspections ui: expand/collapse tree fixed
c0d2162: EA-58395 - NPE: PerlMatcher.matches
d203d8f: bytecode-inferred annotations are only available for compiled elements (IDEA-127608)
5c1256f: Merge remote-tracking branch 'origin/master'
bacc3c2: lambda -> method refs: collapse when acceptable method without supers found
3bed881: Merge remote-tracking branch 'origin/master'
dd4ddfb: method ref -> lambda: names based on resolved method (IDEA-126977)
4b7122b: shorten FQNs when insert casts (IDEA-127573)
91f505e: create static method from usage in interface (IDEA-127563)
124d774: generic debugger settings: step 2 — stepping
72a3ffa: Cleanup (formatting)
7016425: Cleanup (two utility classes merged)
ff16ce7: update about graphics
02939b8: add problems listener to update counter
22a3964: +getList() to access configurables list
79a933c: update problems counter for Darcula
b198c6a: add Problems counter
67cbc12: allow to override layouting algorithm
43ab48e: + getErrorsCount()
72925df: pointless expressions: do not simplify a - b - b to a - 0
824f432: workaround for <p/> inside <pre> in javadoc preview in JEditorPane (IDEA-127430)
ae4f3d9: unwrap: adjust caret before RParenth (IDEA-127580)
a46f4ce: anonym -> lambda: disable in case when inferred type differs from type of anonymous class and parameter of param type is used inside (IDEA-127603); BTW param.toString would be also rejected
89dc528: new inference: no substitution during most specific inference by means of new spec (IDEA-127584)
fb786d3: SSR: improve annotation name value pair matching
20cb223: SSR: renaming
6af6e5d: SSR: Nullable annotations
912772c: SSR: remove unnecessary field
1017a77: SSR: remove a bit of dead code
04d10f8: IDEA-127337 Popups in editor sometimes aren't shown on first invocation
f18c04d: jps plugins: added extension to allow plugins contribute to JPS model even if they don't contribute to external build
5c81146: generic debugger settings: step 1 — data views — merge settings (generic and custom) into one page
4a15d1b: add copyright
27fddc2: generic debugger settings: step 1 — data views
e6d092e: cleanup
343e145: cleanup
90cc9e3: cleanup
30c7264: cleanup
31d8039: cleanup
322e539: IDEA-127077 (highlighting test)
4d7f4ab: move PropertiesComponentImpl to core-impl
2495d31: runtime-opcodes support
f3ffe1a: java-analysis-impl doesn't depend on platform-api
68de28e: use JBColor
fd0bb1e: IDEA-127620 - Clouds: move frameworks to the top level in new module/project wizard
0cf69f8: bytecode analysis: resolve only wrt PsiClassOwner (IDEA-127608)
9ca2a55: reverted e442926 because there is no thread visibility problem right now (per discussion with Roman.Shevchenko)
8e74038: additional tracing code for difference of this session and previous session of particular content calculation
bcd970c: Nullable / NotNull
62a0104: revert: Ctrl-N doesn't show after delete; no input field for Ctrl-N etc
9b4912c: lambda: do not start inference from void type (IDEA-127596)
6de6ee1: delegate methods: do not suggest to delegate when delegate would override final (IDEA-127605)
9ff4e24: plugins update dialog layout (IDEA-127462)
f03ca65: create class: filter out generated roots (IDEA-127562)
455fc35: move destination: fix laziness
d93d0ab: Workaround for another JDK bug in cached popups.
a4cdd68: update grails project structure: remove proper instance of ContentEntry (IDEA-120622) using urls since ContentEntry uses default equals/hashcode implementation
14d57e4: Cleanup (formatting)
e35d9d8: IDEA-127077 (incorrect parsing of type annotations)
653ccf4: move to the right module
0e44e1c: Merge remote-tracking branch 'origin/master'
afc422e: fix errors foreground for Darcula
f38dd67: Merge remote-tracking branch 'origin/master'
bbb42a45d: IDEA-126982 (Add an inspection to flag a nonfinal class that only has private constructors)
c54ff24: fix typos
8ae3019: [git tests] assume git version is supported
1e79d7b: [log] Simplify & fix refs comparison API & implementation
dd0a29c: [git] fix refs comparator for the case when refs have equal names
db96ca3: [git] remove trivial test setup
7f6d1ce: [git] rename test class to match the production class name
d94a9bf: simplify:inline variale
a2d93f2: IDEA-126389 FromString ClosureParams Hint should use method.getTypeParametersList() as a context for creating type because method does not process its type parameters in processDeclarations(). Use method as a context if it does not contain type parameter list
a2221d5: IDEA-126334 Correct declaration scope for light parameters and getReturnTypeElementGroovy for light methods
5ccb872: IDEA-126389 FromString ClosureParams Hint should use method.getTypeParametersList() as a context for creating type because method does not process its type parameters in processDeclarations()
b43f06c: make another IG test light
09fafa8: IDEA-127263 ("Conditional Expression With Identical Branches" deleting non-identical branches.)
feeb54a: SSR: remove unused method
d5ce2c1: SSR: match name value pairs when value is not specified
d61fdb0: fix typo
55eb67a: fixing JspAutoImportTest: auto-import classes at statement start
455b352: cleanup. remove unused fields
42c3f0d: change links protocol
05a4407: add hyperlink listener
9906008: Merge remote-tracking branch 'origin/master'
25f1003: stub for ordered scopes problem
7e4a359: Merge branch 'master' of git.labs.intellij.net:idea/community
3559eb7: bundling ecj-4.4 java compiler
0d34ff1: PY-4186 Lettuce BDD tool support (initial commit of lettuce runner)
640c9a6: Merge remote-tracking branch 'origin/master'
e442926: IDEA-117507 NullPointerException on startup of IDEA 13
d2be1f3: disable hard consistency check
5cc3a16: fix mistype in html+ increase space between elements
2dc1b7c: Log popup window size before showing
1a20228: showing build attempt in logs and in title bar only
2df962a: scopes: include module in file pattern as matching would be calculated against it anyway (IDEA-127397)
d60644a: Resize a popup window according to the preferred size of the component instead of its size.
b237157: do not lock UI during plugin download (IDEA-127454)
067ef9e: method refs: check first parameter if it could be a receiver for varargs methods (IDEA-127506)
eff4567: compose error message (IDEA-127534)
3bc9fa3: IDEA-111466 Mac OS X keyboard shortcuts with alt don't work under Oracle Java 7
6bf1409: postfix template fix ternary operator + test
c6ff466: IDEA-111466 Mac OS X keyboard shortcuts with alt don't work under Oracle Java 7
55a8bd4: DebuggerSettings — use PersistentStateComponent instead of deprecated JDOMExternalizable
189f3f5: cleanup
402ccab: DBE-228: column margins
333636c: Replace comma with ampersand
68ec56f: Add groupId for top-level configurable for Junior IDEs.
2ff73e2: don't recreate code fragment psi (IDEA-127039)
5379b77: turn off contract inference for overrideable methods; hopefully, not forever (IDEA-127518)
49a119a: IDEA-121276 Constant conditions: work with arrays
ec7c9a3: JavaConstantExpressionEvaluator: add @Nullable
563ad9e: move DfaValue calculation for expressions to one place
392885a: @NotNull DfaVariableValue.psiVariable
ee1eb2c: store / use buildAttemptInfo taken from file
5de0503: insert delete with renaming logic for Windows into general delete method
0a6a374: Reverted: cast from Short to char is prohibited (1c5a03589e5155633de91051e59255d3ad84414f)
91b8291: IDEA-123863 'Save Project as Template' action leads to deadlock
3aed563: Platform: use presentable names when generate keymaps for help
34f2fb0: grayed call frame view if in library content (the same as in java)
f9982ec: update grails project structure: remove proper instance of ContentEntry (IDEA-120622)
ecbbac9: Merge remote-tracking branch 'origin/master'
9795ec8: extract from internal mode
3b00516: notnull
67b840e: notnull
e4308c8: cleanup
e75bfff: correctly calculate inspection short name in presence of upsource
52d5382: optimisation
1c5a035: cast from Short to char is prohibited
685fdb4: optimisation: getMaybeSuperClassSubstitutor() allows to avoid extra isInheritor() check
60d088f: notnull, cleanup
b5fb827: optimisation
edf6a02: Merge remote-tracking branch 'origin/master'
23586b9: Added coverage.py fixing wrongly optimized imports.
f291cc5: Fixed getting helper.
ecec042: Merge remote-tracking branch 'origin/master'
f997ddb: StringPattern: restore binary compatibility (broken by 64c812e)
145fbae: Merge remote-tracking branch 'origin/master'
642faba: as ignored file set can be quite large, use map without entries for smaller memory footprint (e.g. in snapshot for IDEA-126201 number of ignored files is 126K, size of entries's memory for this number of elements is 2.5M)
067aa19: skip non-java files with given word in literal even before retrieving text / searching the word / finding element at tree (IDEA-126201)
aea7066: allow to pull methods in super interface as default ones when super interface already contains a method with the same signature; remove @Override in such case (IDEA-126988)
7d19e0e: method refs: missed super class substitution (IDEA-126969)
f17f398: 'unmark root' action: allow user to cancel exclusion if excluded folder is selected (IDEA-23537)
d61da37: IDEA-122076, IDEA-122172 Multicaret actions in quick find mode
8b2824d: IDEA-121956 Multiple Carets: Add support for skipping next selection
1ce6009: - catch runtime problems (e.g. IndexOutOfBoundsException from ByteBuffer) when instantiating stub index and retry index creation (IDEA-117596, IDEA-125750), ep2
c455dd4: - catch runtime problems (e.g. IndexOutOfBoundsException from ByteBuffer) when instantiating stub index and retry index creation (IDEA-117596, IDEA-125750) - use deleteWithRenaming to update index version (IDEA-127160)
b0fe937: DirectoryIndex: fixed 'isIgnored' for ignored files
fb4de8d: DirectoryIndex: store info for excluded and ignored directories
df68af8: require that notnull fields be initialized (IDEA-114889)
5a22fdc: IDEA-126660 Incorrect 'condition is always true' for a final field if an overridden method is called from the constructor
a7ec8b7: IDEA-126173 Specify exception type thrown by @NotNull annotations
f4d3703: IDEA-126531 Completion inserts unwanted semicolon
2887069: dfa: take into account known variable values when handling number comparisons (IDEA-126446)
1aa6e7a: add cast to disambiguate method calls when replacing their argument with null (IDEA-126466)
65ccc19: HardcodedContracts: use a utility method
4853112: dfa: we don't replace nontrivial references with constants, so remove the corresponding code and tests
3eea5bc: hardcode Guava Preconditions.checkNotNull contract
6d9cf39: dfa: understand assertThat notnull (IDEA-125977, IDEA-65004)
2a3e157: Merge remote-tracking branch 'origin/master'
f5e85e7: IDEA-126122 (reFS volumes recognized)
be1c5b8: Refactoring: configurable from provider can be null
e568624: Cleanup (file watcher project converted to VS13; generated junk dropped; version info updated)
1e7a9e9: Cleanup (tabs/spaces; formatting)
0262088: cosmetics: add extra offset for project icon and label margins
1695e0c: fix AIOOB in history
2b3dd78: add css styles to Error Pane
ac796ba: wrap errors to html for new project structure dialog
59763f3: Focus logging
3d07af1: SingleInspectionProfilePanel NPE fixed
397e893: IDEA-127478 Tip Of The Day dialog could be shown on incorrect monitor
090b2e5: on case-insensitive file systems perform file name compatibility check using real file names, not the ones taken from dynamically built or stored paths
e77cd8a: imports optimized
444f98b: show tooltip when mouse on "multiscopes" icon in inspections settings ui
b0b0fef: external build: send empty text with statistics message to avoid producing unnecessary output by IDEA Project Runner in TeamCity
970fe60: use ProjectFileIndex (from API) instead of DirectoryIndex (from impl) where possible
d9c45be: libraries scope: use ProjectFileIndex (from API) instead of DirectoryIndex (from impl) where possible
417adc7: notnull
b58808c: js postfix templates -> fix examples and configurable UI
ba3b637: Settings dialog: the project-based configurables are marked with an icon.
6508417: IDEA-127438 Tool windows drag&drop failure under Java 7
ca76151: IDEA-127343 Github: pass ModalityState to PasswordSafe
da5b7e6: use Couple
e98cb25: use Couple
568b881: DBE-228: abbreviate long cell values
abd5dce: notnull
6d84ba6: Add image to visualize the project-based configurable in the Settings dialog.
c32d9db: [vcs] IDEA-107598 Affected paths: consider the whole path when highlighting
f4ee468: Inspections settings ui: new inspections tree (tree replaced by table tree, added icons represent severities)
47de3cf6: LiteralExpressionTokenizer cleanup
120fe08: get rid of group border
1a5cf59: IDEA-127343 Pass ModalityState to PasswordSafe.store/removePassword
0143935: remove trivial javadocs
f3eb2b2: [git] Remove obsolete password aware handler
c4a16ff: Get password called with modality state; unnecessary get password from memory removed for hg auth
bf1f916: restore API for idea-php-symfony2-plugin
c53dc62: check for null
62e5744: unused classes from 'old make' implementation deleted
b8ddfa4: groovy compiler: deleted classes related to old make implementation
42926e1: Fix possible NPE in JiraRepository (EA-58392)
3498760: Introduce live integration tests for Tasks plugin. Add initial version of such tests for Trello
6fd747b: Migrate TrelloRepository to new tasks API
3021914: Remove wrong GSON annotation of 'closed' field in TrelloCard
e2b581a: IDEA-115177 (watcher size check no longer needed)
c9d3e32: vfs: file watcher executable lookup fixed
431f9db: get rid of deprecated code
25c8ccd: EA-58277 (diagnostic)
6037400: don't highlight '*.restartRequired' properties in registry.properties as unused
dfb7e51: registry: use 'restartRequired' property to enforce automatic restart
3305c35: registry: description text corrected
0ffc7d0: CIDR: OC-10422 Current resolve configuration should be preselected in resolve context panel
5f31e2e: show excluded files in Project View, initial (IDEA-23537)
ace6fe4: artifacts: one more unused class from 'old make' implementation deleted
5897a01: deleted old unused deprecated 'build participant' classes
b75d5f2: artifacts: unused classes from 'old make' implementation deleted
3ed24eb: RUBY-15507: we should not wrap configurables in scroll pane
26b2743: ProjectViewPsiTreeChangeListener updates tree more deeply on property changed
77ee53a: Fix again the following changes that were reverted: Fix for nullable composite configurable.
d0cd301: IDEA-126984 Mac OS X: Double line above the editor
c2e6ab0: revert (e3e3224e853ad466cebf13c8b5c7f01d272d8e88 Fix for nullable composite configurable.)
d1ce059: highlight modules
8b6c40d: platform: splash misalignment on Windows fixed
8b35719: devkit: incorrect modification reverted
928feba: JavaHelp 2.0_05
bc13d12: Merge remote-tracking branch 'origin/master'
a9d7da6: added test for default property file in resource bundle editor
160fca0: project: windows update scripts unified
e3e3224: Fix for nullable composite configurable.
a69f781: cleanup
aa16ba2: IDEA-126984 Mac OS X: Double line above the editor
0994232: project: build/update scripts tuned to support home paths with spaces
b9eb20d: EA-57720 - PIEAE: LeafPsiElement.a
1396322: IDEA-127343 Pass ModalityState to PasswordSafe.getPassword
7eb4791: [git] remove obsolete javadoc
4d3abb7: cleanup: remove trivial comments
d8f6d4c: SeverityEditorDialog -- if "mixed" pseudo severity chosen then no default selection
e39d6a2: ScopesAndSeveritiesTable suppress unused declaration inspection
f356442: DBE-321: prevent data tooltip flicker
226e175: Inspection settings UI: multiselection in inspections tree support
68c651e: catch exception when writing content, marking vfs for rebuild (IDEA-125925)
f59b7b3: revert the change that breaks functionality
eac71fe: add tool window id to assertion
349f84a: fix several concurrency issues in Search Everywhere
65824bb: Some configurables requires the dynamic attribute to configure its wrapper properly.
73c7f62: go to action: move Analyze Stacktrace... to the top
5458ff1: IDEA-127232 Fatal Error on startup on Mac Os X
09230b2: IDEA-125671 "Install plugin from disk" action could have different description in Find Action list, because now there are two identical items in the list
35e6c4d: remove suppressions
e83f80f: implicit usage provider for *.description in registry.properties
ddae39a: file path completion fixed
6f1f6cf: Inspection settings UI: creation copy of tool wrapper if new scope inserted
981a3db: remove unused class ColumnInfo$StringColumn
864cd2d: Inspection settings UI: - "ALL" scope moved to last position in table - move scopes in single inspection disabled
4965683: Merge remote-tracking branch 'origin/master'
e488923: cleanup. remove unused methods
d13074e: fix incorrect target element calculation for text editors
e2c4550: typo
219b31c: show display name for certificate configurable
1b4a3c1: larger scope when searching in path / ssr (IDEA-127068)
17a5843: disable plugins if cycle was detected (IDEA-127177)
001a9cf: New inspections settings UI: - nodes for individual scopes deleted from settings tree - added table in right panel to configure scopes&severities - new scope button added to right panel (if only default scope currently available)
de377f8: extract variable missed events (IDEA-127166)
dcb45f2: extract field missed events (IDEA-127167;IDEA-127169)
1d8d358: extract parameter missed after event added (IDEA-127170)
30d945d: local rename events (IDEA-127172; IDEA-127172)
d0b86b6: popup position for injected fragments during inplace refactorings should be calculated over injected editor as caret range marker is against injected document (IDEA-126989)
53de53f: Refactoring of grouping configurables. Use the following registry key to switch on this functionality: ide.file.settings.order.new
088e9a2: Fix tests broken after changes for PY-4073
d5032e5: java: parser changes temporarily reverted
690797e: Using "Batch File Change" events in BuildManager to cancel already running automake session while VCS is updating working tree (IDEA-111673)
4e586b4: replace with foreach
b70bfe3: Platform: do not produce duplicating shortcuts in help keymaps
d65ce21: Merge remote-tracking branch 'origin/master'
6a141b3: [git] rename utility method to a more consistent name
c5129cf: fix layouts: exclude structural search from defaul platform implementations
a9396b6: unused property inspection: search in a narrow scope first
5002c70: contract inference: honor already known parameter values during data flow analysis
704198c: contract inference: exclude contracts not matching the return type
349f900: no ContractInference for compiled elements
f02a497: change foreground and separator color
2e6fb66: move Problems down and change separator
6404449: support "--" separator
aa98745: customize separator
2e376b2: [git] IDEA-126472 IDEA-126473 Notify about external changes modifying the working tree
1a37016: [git] better diagnostics output format
f9a615b: [git] remove unused method
8b2eae6: [git] Remove duplicated code
5dd8682: Merge remote-tracking branch 'origin/master'
91b1e1b: Fixed wrong cast.
44ec294: annotate getPattern / getOptimizedIndexingPattern with @Nullable return info
50d32b8: SSR fix replace test
6521af0: IDEA-127077 (incorrect parsing of type annotations)
5b72fac: Cleanup (warning)
4fd07a5: License dialog: License key: provide precise diagnostic for rejected key After-review
6cb2eab: Remove deprecated Remote Interpreters API.
7d1e1bd: do not propagate exceptions in case of broken bytecode
980b837: fix test
e099a14: gant-based builds: added one more jar required for Kotlin compiler
f36393b: go to action: use gray instead of italic for shortcuts rendering
1c43998: gant-based builds: removed incorrect classpath entry for Kotlin compiler
ffb8b5f: gant-based builds: added jars required for Kotlin compiler to classpath
47eec66: java inheritor cache: use weak map to avoid holding PSI for unnecessary long time
1a78fe7: goto action: restore enabled action preference
8343e8e: goto action: rewrite using a more suitable API, prefer exact matches, fix search everywhere
a24b862: IDEA-127189 Select next/all ocurrence fails with braces
304a69b: IDEA-103025, EA-53787 fix handling of special fonts in soft wrap model
dd4b761: trait field searching test fixed
7c04faa: Merge remote-tracking branch 'origin/master'
bad2fa8: Fixing env tests
dd23104: memory hogging on javaInjections.xml editing
1bbb89c: go to action: proper text attributes for shortcuts
0057fe3: go to action: don't show duplicate group for intention actions
482084c: go to action: missing bg for option descriptors
590ed4c: disable create instance field inside interface (IDEA-127211)
65d11dd: disable generate test method actions outside class (IDEA-127246)
f69f9fd: leave static modifiers in interface methods (IDEA-127255)
42f50f6: sort items in goto action by matching degree (IDEA-112613)
45915b2: show colored matched fragments in goto action (IDEA-112613)
34b51a1: show progress when status bar is switched off (registry: ide.show.progress.without.status.bar)
cdbb650: null check
d5dada4: disposed check
64c812e: StringPattern: cleanup, add StringPatternTest
7fa1b28: remove unnecessary field and getter from SSR ReplaceCommand
472bf3f: java: decompiler fixes (IDEA-127229 et al.)
7ada79c: AnnotationUtil.isInferredAnnotation
c0d76a2: parameter info: don't retrieve inferred annotations in dumb mode
4df5903: IDEA-127127 charset name completion: provide completion for more APIs
b6ea24b: don't duplicate annotations in parameter info
3f7935a: dfa: turn on contract inference from source
b6b76b7: IDEA-127212 Live templates "Use static import if possible" fails sometimes
f372b95: corrected 'isCommunity' check
08b3c7f: disable table speed search for empty tables
51292ab: Merge branch 'svn_18_3'
511f071: IDEA-126911 Do not call "VirtualFile.getFileType()" for directories (while checking if annotate action is enabled)
93e45b9: PY-4073 Add completion for special function attributes
0a5bfb0: Merge remote-tracking branch 'origin/master'
0fcfb36: Merge remote-tracking branch 'origin/master'
86b7bf5: Fix copying .egg files from remote host to libraries folder (PY-13044).
912c0d7: html editor as a error pane
55b4064: do not modify profile file to write default
102bcb2: structural search bundles fixed
bb0b50c: Merge remote-tracking branch 'origin/master'
5253ba2: type migration: make part of platform
3ab8864: Error pane initial
581cf80: structural search: groovy should work in community
76726e8: disposed check
be28458: css synchronizer — support of manual update
7b29836: structural search: make part of platform: enable in community
a5061f3: fix module locations
a3626d6: Merge remote-tracking branch 'origin/master'
695682b: structural search: make part of platform
50e27ec: enable inline redundant local vars in batch mode (IDEA-126957)
49b9f30: EA-58014 (diagnostic)
9d32e98: added incompatible plugin version org.intellij.clojure / 0.2.1.178
c27d829: - properly retrieve set of keys for unsaved documents for their first change - (in extra sanity checks mode) added PHM that stores previous content indexing info to facilitate discovery / fixing assertions about different indexing behavior
0896a25: avoid accessing invalid buffer
159f3c5: Merge remote-tracking branch 'origin/master'
4cc0d5e: IDEA-127183 Windows: Look for 1.8 JVM registry entry by default
f41f9c3: Debugger reader performance fixed, now uses BaseOutpuReader (PY-11393).
cb2159e: Switch on new Alt processing under Windows L&F.
ef8fbc4: notnull
e1445e6: Gradle: IDEA-127217 Tests with spaces aren't wrapped with " " when running specific test as Gradle test
cf1f8c8: fix tests: improved 'isInCommunity' check
bcb38e5: pep8.py updated to version 1.5.7
0970549: Coverage.py updated to version 3.7.1
90f034d: Merge remote-tracking branch 'origin/master'
6ec557a: Try even more to connect.
69a2a4c: path completion: rendering fixed for several matched context helpers
21efa65: cleanup
7494ef6: support for multiple groups in idea.test.group property
00847ed: No need to register MessageBusConnection disposal: it is done automatically
0fb6eab: Suppress "unused" constructor: initialized as a Service
2b6b549: Fix already disposed EA-58257
fc46e99: look for JVM 1.8 first
b7cea46: added caching + minor size opts
63453c3: fix NPE in SSR ReplaceOptions
941c20b: stop usage search on target invalidation (EA-54329)
d75a12f: invalid type diagnostics (EA-58069)
121084a: remove specific Lookup check in intentions pass, daemon is disabled during lookup anyway (EA-58246)
71fd543: WEB-9954 move and rename confusing "Live Edit menu item
5d745b1: check for null for content hashes flush
7073116: fix ConcurrentMapsTest (by Roman)
6d6d15a: IDEA-122254 ("Use static import if possible" checkbox for the Structural Replace dialog)
4febd80: intention should insert static import when replacing assertNull() with assertEquals()
4dd5b62: insert static import when replacing assertEquals() with intention
591d723: insert static import when flipping assert literal outside of test method
90f2ef5: use static import if it is already present for several intentions and inspections
dd2d141: Merge remote-tracking branch 'origin/master'
ae714aa: Win tests should be more stable now
3b3fee8: clear zip file caches on low memory
c81ebf5: Refactoring: create instances of IdeConfigurablesGroup and ProjectConfigurablesGroup in one place.
b83f901: Merge remote-tracking branch 'origin/master'
9c13559: Comment.
ec56a95: skip leading .* in reg exp used for todo pattern when building index: it makes sense for todo highlighting but increases matching due to backtracking enormously (IDEA-74104)
d83e334: IDEA-126836 Formatting adds extra blank line after class header if it ends with comment
6d68662: use 1px separators
e360f62: add utility method to configure 1px separator
23ba8f8: use encoding info when building hash for contents + rebuild content dependent indices upon encoding change
7b8cc6c: Fixed according to CR-IC-5706
93d37fa: don't auto-import classes where class references are prohibited syntactically (IDEA-127190)
f87e56d: bytecode analysis: a comment about lite control flow analysis
90addcd: bytecode analysis: lazy resultOrigins analysis
a7c1c1a: bytecode analysis: lite control flow analysis
8211223: bytecode analysis: no analysis at all if nothing is inferrable
60a6acf: moved method from moduleutils to modulerootmodificationutils
3173594: jetbrains.dic + "unmerged"
c95ca18: support prefix expressions in quick evaluate
8d71285: cleanup
e418bb2: use UIUtil.getSidePanelColor()
bef8a7f: remove border for content component
1835567: + side panel color
105b9a1: @Nullable
ef2875d: IDEA-126927 - CloudFoundry: if the same artifact is deployed to few clouds, one can view the state of the single one only
7c415ca: IDEA-127069 help button added to the Mercurial Update Project dialog
0e12675: Revert "StringUtil: Added wordWrapString() method"
5af9e9f: separator titles for Darcula
b044185: better IDE responsiveness during bytecode indexing
15ed602: svn: Fixed converting SVNStatusType to StatusType - explicitly check values that have non-unique status type names
43b6e08: BytecodeAnalysisIntegrationTest: a more profound test data refresh
525a896: Merge branch 'master' of git+ssh://git.labs.intellij.net/idea/community
fe15e86: bytecode analysis: index version increment
0d24afe: disabled batch evaluator by default, overhead is too high. Enable if needed using registry key debugger.batch.evaluation
0069112: added nontull
062254d: svn: Refactored SvnStatusHandler - moved status type parsing to StatusType class
a884c1b: ignore inferred annotations when checking overriding parameters nullability
b6b6ea1: bytecode analysis: lite persistent hashCode for Configuration
1f05788: bytecode analysis: skipping frames and debug instructions
aa3b189: svn: Refactored StatusType - removed deprecated STATUS_MERGED value
f2d0988: do not capitalize titles
5ba1390: extract CachingEnumerator from PersistentStringEnumerator
1cd8961: IDEA-126973 IDE does not see the use of string resources in libraries
bb0b856: @NotNull
b700084: nullable/notnull/contract intentions available on library sources in Groovy
18afce3: external/inferred annotation gutter markers in Groovy
18dcabb: [vcs] assert annotationProvider != null (otherwise the action shouldn't be enabled)
ff89749: [vcs] Handle all exceptions during annotation similarly. EA-58021
45cd16b: svn: Refactored SvnVcs.svnStatusIs() - method moved to Status class
37423bb: StringUtil: Added wordWrapString() method
228a7f0: IDEA-127144 (No word wrap or horizontal scrolling for ignore list in Proxy dialog)
a570ab1: SSR: remove unused code from replace options
e19e11f: SSR replace handler cleanup
ab42788: IDEA-125021 Improve multi-caret copy-paste logic
8662259: IDEA-127125 Throwable at com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter.reload
7c0fcae: fixed Breakpoints tests
be3789a: do not calculate source position twice
a22e159: Disable css emmet fuzzy search by default
687fa76: no need for findClass if we have object already
86d795a: ElementPatternCondition: less memory
7801b62: ObjectPattern.oneOf(T...): less memory for single value
394b9f4: GPUB: keyword completion on non-trivial offsets
d9d79ac: resource bundle editor property rename fixed: no property with old invalid name creation after rename
233bdf9: svn: Replaced SVNStatusType (from SVNKit) with custom StatusType enum
5803898: action popups are broken if new project settings dialog option is on
1b4fef2: svn: Replaced SVNEventAction (from SVNKit) with custom EventAction enum
cbcc65f: more robust lookup start offset invalidation tracking (EA-51961 etc)
4703c93: IDEA-75885 Fast invoking shortcut with Alt brings focus to main menu [Windows] IDEA-87408 Hold <ALT> button and select multiple lines vertically does not work as desired
19eb679: Add diagnostic info
40acdf7: License dialog: provide precise diagnostic for rejected key (IDEA-122894, IDEA-125916, IDEA-125917, IDEA-125921)
e28ee1b: display inferred annotations in italic
fe21a09: IDEA-81781 Unintuitive 'Project Files Changed' message box
78b8b2c: Fix emmet tests
b363ad7: notnull
ac8bf17: added comment
d61930f: revert 43b0575239264eef2d4a5299b48f3d2119d8d380
3674c5e: PY-13140 Fix several minor issues found during code review
99058ce: TableView: update only visible column sizes
4a8c1f7: fix BytecodeAnalysisTest?
6563b56: fix BytecodeAnalysisTest?
f6c970f: IDEA-126896 Gradle: Grails integration buildPlugins issues
1ee9d0e: ModuleWithDependentsScope, another minor post-review cleanup
1478698: Fast groovy tests: exclude external system integration tests from FastGroovyTestSuite (e.g. GrailsGradleImportingTest)
43b0575: IDEA-126836 Formatting adds extra blank line after class header if it ends with comment
abcc172: IDEA-127062 Bug when closing splitted editors
ee204e9: IDEA-127045 Unexpected 'step over' behaviour in debugger
a2fb7f6: DBE-60 Windows Authentication for SQL Server
79fc7d2: processing vcs changed text only if we are not processing selected one
0f34d80: Add diagnostic info
f506a15: PY-13140 Underscored names are completed inside import statement
e0ddef7: PY-13140 Top-level module names starting with underscore are not imported via wildcard import
b6eee00: fix PushedFilePropertiesUpdater registration
b9e4b83: BytecodeAnalysisIndex is only in idea
4dfa351: BytecodeAnalysisConverter is only in idea
cb79e2e: if editor has selection, reformat only selected lines, when reformat dialog is not shown. Do not take into account processChangedText flag
76ed9f7: Merge branch 'master' of git.labs.intellij.net:idea/community
c3c78c5: IDEA-93948 Code Style->XML->Other: no preview text for CDATA
d08111d: XML Colors settings: fix description text (missing line breaks)
34dcb63: SSR: remove unnecessary class
472994b: remove some dead code from SSR search dialog
fca4af3: more efficient shortening of class references in SSR
560fb1c: fix not-null assertion
e13715a: fix NPE
9665337: javascript-psi-impl shouldn't depend on lang-impl
2a91d19: fixed XBreakpointManager.testSerialize
f698722: ModuleWithDependentsScope minor post-review cleanup
9d399a3: WEB-12568 Dart autocomplete deletes closing bracket
95673d1: don't use getPackage to check if PSI directory is in source (SCL-7243)
fbbb221: bytecode analysis: copying to prevent indices/enumerators issues
831ab18: bytecode analysis: compound keys - maximizing shared stuff
0ddd915: enable inference bytecode indexing only in internal & test mode
ee888c2: fix AnnotateMethodTest
e0861b8: bytecode analysis: leaking parameters analysis
31d93dc: ProjectBytecodeAnalysis -> service
fbb2825: ignore inferred annotation in @NotNull propagation to overridden methods
1b75318: adapt testdata to inferred jdk annotations
f350b3d: hold inferred @NotNull annotation on a hold reference to avoid UsageViewTest failures
0e53e62: bytecode analysis: assume that errors are due to incorrect bytecode
affe6e0: log bytecode analysis related information with debug level
a11744c: adapt dfa testAlexBug to jdk notnull inference
f98006e: ProjectBytecodeAnalysis: use tree hierarchy to find parameter's declaring method
bfbc9e0: limiting number of elementary steps of bytecode analysis to 30000
8eee4f3: import fix
261018e: logging AnalyzerException
ce0e838: bytecode analysis: increase IDE responsiveness during large class file analysis (e.g. groovy's ArrayUtil)
3357716: bytecode analysis: use separate keys for each file to avoid O(n^2) index removeAssociatedValue
7fc5d9e: make BytecodeAnalysisTest more classloader-agnostic
bd2ebf1: cache enumerator data, remove unnecessary enumerator queries
14ed555: do postponed formatting in JavaChainLookupElement (EA-56040)
ce64501: no contract annotation if method is already @NotNull
1754869: findInferredAnnotations returns @NotNull array
3b75ca1: refresh annotations dir during setUp
6dd49cb: update annotations after mockJDK update
c5f3f23: hashCode via ordinal, copying equations into solver
90e6e0d: myAnnotations are volatile
08811b0: more logging
1e54e26: simple smoke test that inferred annotations are visible to codeInspection
0db25e9: arrays and primitive collections
658b710: aligned with faba
b993ee5: NPE fix (possible dead bytecode instructions)
8de3dfd: using TIntObjectHashMap in analysis (instead of wrappers)
0ea01ef: minimal structures for inferred annotations in memory
861fbc7: reload inferred annotations on root change
92e2f07: checking enumerators during converter initialization
338481d: Bytecode analysis tests
75eb3cb: straightforward solver
7056873: rigid infinum
6220d1a: porting faba features
ecce111: Contract clauses normalization (sorted)
cd2946b: Tuning null -> ... analysis
82e7fd8: Parameters: CNPE join CYCLE = CYCLE
ade7530: stable calls (ported from faba)
657b7af: starting integrations tests
70cc7af: qname may be null (anonymous classes)
f2e3270: smart propagation (resultOrigins analysis)
05486ff: separate indices
eb58968: a proper disposal of app component in the test
1901b35: this is NotNullValue
f8a153e: equals/hashCode for index values
6dcf377: comments + refactoring
383752b: compound indices in action
ff84337: initial implementation for compound keys
d905c85: towards compound keys
68ef299: Refactoring: moving class processing into DataIndexer
c8e0bef: towards compound ids
bacb5f5: extracting converter
655e0ba: poc implementation via indices
eac23b5: indexing
dabdf64: towards indexing
10fda95: emulating touch via special value
e1fce3d: No need for components (with touched flag) in raw equations
44ea307: testing contract annotations
a8717a4: testing hand-coded classes
fb6ce34: Start test for BytecodeAnalysis
8ec604c: using (naively yet) solutions of IntIdSolver in Idea
fc86f2b: full cycle of solving (not tested yet)
1d2c7d5: in progress: internalizing equations
c31fd4a: No need for signatures
41d2da1: poc usage of enumerators
073012d: inferred annotations in gutter
8c57905: Draft implementation of inferring Nullity and Contract annotations
dca785b: stub for inferred annotations
d83c897: @notnull
aeb0b27: allow / skip build attempt number e.g. IU-135.455.10 (IDEA-122579)
604ec3a: Add workaround for CertificateManager *service* to work with old task connectors
b96c582: Rename classes related to legacy JIRA interface to not cause confusion anymore
165465c: IDEA-123972 Display JIRA version under JQL editor field in settings
6708af2: Use simpler test API for performing actions
eb009fc: introduced expandNodesOnLoad in XDebuggerTree
1c3cefb: nice diagnostics for failed assertion about same indexing result from the same content
6b75304: IDEA-127042 Create tip of the day for quick evaluate
b8d6082: add to watches with control+enter from evaluate dialog
86d958c: for nonntrivial file systems (e.g. in tests): build todo data flag should have the same value as todoindex.isAcceptable (cherry picked from commit 5213e01)
962d04b: svn: Refactored SyntheticWorker - reused default DirectoryEntry comparison for sorting
99e9710: IDEA-107376 Goto next / previous splitter not working when show tabs are set to none (Carlos Ortiz)
0ce61f1: notnull
a0f6b0a: svn: Refactored "checking node kind" logic - use utility methods (instead of direct comparison with NodeKind enum values)
2b5e1c1: update breakpoints and execution line highlighters on color scheme change
69be4e2: svn: Refactored RepositoryBrowserDialog - removed duplication and simplified "set action enabled" logic
e438d20: Merge remote-tracking branch 'origin/master'
1cc9650: IDEA-122894 License dialog: License key: provide precise diagnostic for rejected key (cherry picked from commit ff0eada) (cherry picked from commit 29c98ba)
9241cae: Merge remote-tracking branch 'origin/master'
7d896bb: provide completion variants for Charset.forName() in Groovy (IDEA-126595)
e62b6df: IDEA-126973 IDE does not see the use of string resources in libraries
02e5ede: updated javadoc for exit and restart actions
e1d0804: WEB-12677 Emmet: do not expand too long abbreviations
6046586: Emmet: preview editor should have maximum width if softwraps are enabled
be20e87: DOC-3246 IDEA: Update master password dialog panels help
ca5260d: IDEA-79083 Popup lists are sometimes not clickable
8a05f8e: Merge remote-tracking branch 'origin/master'
be76dc1: highlight matches in plugins table
fcd53e5: save search query as a client property
fd6b2c9: add a client property key for search query
febbd75: fix inspection setting
e119956: svn: Simplified node kind values parsing - parse right to NodeKind enum (using jaxb annotations)
6979d52: do not let transient iterator escape as it references nonsharable thread locals
746de0c: diff: fix example in diff editor color settings
3eebc8b: show different icons for muted enabled/disabled breakpoints
1b1a23a: IDEA-120465 Code completion: no Autopopup code completion and inserting pair brackets if Column selection mode is on
9dde9e3: svn: Replaced SVNNodeKind (from SVNKit) with custom NodeKind enum
ed3bf70: split 'force' flag into two different ones: 'force' and 'exitConfirmed', so that now 'force==true' guarantees application shutdown; (fixes also IDEA-127009)
756bc03: performance optimization (following IDEA-CR-337)
7a94893: change storage format for smart backspace configuration (following review CR-IC-5570)
8feafdf: Updated tests due to changes in interface of CommentByLineCommentAction
5d8aeec: IDEA-127074 Executing gradle script fails with error '.../build.gradle' is not a directory
546e0ba: IDEA-88643 delete item from list of breakpoints by pressing delete key: selection should not return to position 1.
4de85a6: IDEA-122513 Can't expand single character property in Spring config
2595051: fix blinking test
51305d0: fix test (following IDEA-124928)
51c9f4a: IDEA-121060 Multiple carets: comment/uncomment works incorrectly
0ddcf6e: IDEA-121060 Multiple carets: comment/uncomment works incorrectly
d51dd50: IDEA-121060 Multiple carets: comment/uncomment works incorrectly
9307f63: svn: Save selected depth for update/integrate operations in configuration
0e44683: svn: Refactored DepthCombo - use custom renderer to display presentable depth labels (instead of separate DepthWithName class)
c20bfe7: svn: Replaced SVNDepth (from SVNKit) with custom Depth enum
0e8564a: Merge remote-tracking branch 'origin/master'
c3e78ad: Add read action.
54474d0: TestDataGuessByExistingFilesUtil: prevent thread starvation and use processor to avoid several huge String collections in the memory (IDEA-127038)
02c1b76: svn: Utilized CommitInfo when parsing "svn list" output and for DirectoryEntry implementation
ac00218: svn: Unified "lock" information parsing for info, status and browse clients (utilized Lock class for all cases)
3ea1e9e: Merge remote-tracking branch 'origin/master'
61c9bc4: highlight matches in selected search result
e3fd6eb: don't add a newline when completing with smart enter shortcut (IDEA-126726)
4029019: EA-57959 - ISE: DomInvocationHandler.getAttributeChild diagnostics
e3c7a70: don't require PerformanceWatcher unresponsiveness threshold to be divisible by unresponsiveness interval (IDEA-127038)
02b931c: diff: fix NPE
dc4f600: Merge remote-tracking branch 'origin/master'
bcc88e8: svn: Replaced SVNLock (from SVNKit) with custom Lock class
f21bc13: svn: Replaced SVNDirEntry (from SVNKit) with custom DirectoryEntry class
8434e55: svn: Fixed NPE in SvnKitBrowseClient (SVNLogClient.doList() logic) - use SVNRevision.UNDEFINED if null is passed
e6f257f: Added multi-associations in win (un)installer with the controls on the option page.
6eb7f53: svn: Replaced ISVNAnnotateHandler (from SVNKit) with custom AnnotationConsumer class
535cb8c: svn: Refactored SvnRemoteFileAnnotation - removed unused fields
56cd6a8: svn: Refactored BaseSvnFileAnnotation - utilized CommitInfo for implementation logic
6916bac: svn: Refactored BaseSvnFileAnnotation - code simplified, duplication and unused code removed, warnings fixed
79f167e: svn: Utilized CommitInfo when parsing "svn annotate" output
5585db2: svn: Replaced SVNCommitInfo (from SVNKit) with custom CommitInfo class
3b0971e: svn: Replaced SVNDiffOptions (from SVNKit) with custom DiffOptions class
58ab1b9: svn: Replaced SVNConflictVersion (from SVNKit) with custom ConflictVersion class
d287078: svn: Fixed "memory leak" error (on application close) after viewing merge source hierarchy details - correctly register dialogs for disposal
ef3bc87: svn: Refactored TreeStructureNode - made not to be generic, renamed
ff2698d: svn: Unified LogEntry and LogEntryPath with corresponding similar classes used for svn executable xml output parsing
00224be: svn: Replaced SVNLogEntryPath (from SVNKit) with custom LogEntryPath class
6a330b5: svn: Replaced SVNLogEntry (from SVNKit) with custom LogEntry class
615f0cb: svn: Refactored parsing of child xml elements collections - use @XmlElementWrapper (instead of intermediate classes)
5ac00c0: svn: Refactored SvnUtil - moved "getPathForProgress" to ProgressEvent
cef6176: svn: Refactored ProgressTracker - removed unused method parameters, make inherit ThrowableConsumer
17cbb94: svn: Replaced SVNEvent (from SVNKit) with custom ProgressEvent class
57e1c41: svn: Preserve several more used fields when converting from SVNStatus to Status
37798c0: svn: Allow @Nullable values when converting SVNKit types to corresponding svn4idea types
ea32a54: IDEA-125627 Added new conflict reason values available in svn 1.8
099870d: svn: Replaced SVNConflictAction, SVNConflictReason, SVNOperation (from SVNKit) with corresponding custom enums
6dc734f: svn: Replaced SVNTreeConflictDescription (from SVNKit) with custom TreeConflictDescription class
57db2a5: svn: Replaced SVNStatus (from SVNKit) with custom Status class
6730240: svn: Replaced SVNInfo (from SVNKit) with custom Info class
b527300: svn: Removed unnecessary IdeaSVNInfo - directly use SVNInfo instead
46fdb20: svn: Refactored UpdateClient - make methods throw SvnBindException (instead of SVNException from SVNKit)
9ccd315: svn: Refactored StatusClient - make methods throw SvnBindException (instead of SVNException from SVNKit)
bb3582d: svn: Refactored RepeatSvnActionThroughBusy - make methods throw VcsException (instead of SVNException from SVNKit)
33b3795: svn: Refactored InfoClient - make methods throw SvnBindException (instead of SVNException from SVNKit)
ab74ce3: svn: Refactored CmdInfoClient - removed duplication, methods extracted/inlined, @NotNull
29f24cf: svn: Refactored CmdInfoClient - inlined "doInfo" methods, removed duplication
17d79f7: svn: Refactored UpdateClient - removed unnecessary methods
19cc497: svn: Refactored StatusClient - removed unnecessary "doStatus" overload method (call replaced with more general overload)
faa09ef: svn: Refactored StatusClient - removed unnecessary methods
b45cfaa: svn: Refactored StatusClient - removed unnecessary "doStatus(File path, boolean remote, boolean collectParentExternals)" overload method (as always invoked with collectParentExternals = false)
ae24d84: svn: Refactored InfoClient - removed unnecessary methods
2e97768: svn: Added some todo items for working copies of 1.8 and greater formats (cleanup, nested working copies file status refresh)
7874cb3: svn: Refactored SvnCheckoutProvider - removed unused parameters, @NotNull
22b2900: svn: Refactored SvnCheckinHandlerFactory - code simplifications, warnings fixes
1ce0847: IDEA-118540 Refactored "committing changes to same repository but from working copies of different formats" detection logic, updated confirmation message
491ac7d: svn: Updated working copy format checks to be "weaker" - to correctly support working copies with greater than svn 1.8 formats
Change-Id: I25f808eb8c86e4bd21610b40ab6b6df310d8e636
Diffstat (limited to 'platform/platform-impl/src/com')
109 files changed, 1892 insertions, 1107 deletions
diff --git a/platform/platform-impl/src/com/intellij/codeStyle/DefaultCodeStyleFacade.java b/platform/platform-impl/src/com/intellij/codeStyle/DefaultCodeStyleFacade.java index bf748ab945ba..4d9a34a029b5 100644 --- a/platform/platform-impl/src/com/intellij/codeStyle/DefaultCodeStyleFacade.java +++ b/platform/platform-impl/src/com/intellij/codeStyle/DefaultCodeStyleFacade.java @@ -19,6 +19,7 @@ */ package com.intellij.codeStyle; +import com.intellij.lang.Language; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.options.Configurable; @@ -39,7 +40,7 @@ public class DefaultCodeStyleFacade extends CodeStyleFacade { return "\n"; } - public int getRightMargin() { + public int getRightMargin(Language language) { return 80; } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java b/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java index 88d3aa285960..26a6f6356d2a 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/PerformanceWatcher.java @@ -45,7 +45,7 @@ public class PerformanceWatcher implements ApplicationComponent { private ThreadMXBean myThreadMXBean; private final DateFormat myDateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss"); //private DateFormat myPrintDateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); - private File myLogDir; + private File mySessionLogDir; private int myUnresponsiveDuration = 0; private File myCurHangLogDir; private List<StackTraceElement> myStacktraceCommonPart; @@ -98,9 +98,9 @@ public class PerformanceWatcher implements ApplicationComponent { } }); - myLogDir = new File(PathManager.getLogPath() + "/threadDumps-" + myDateFormat.format(new Date()) + mySessionLogDir = new File(PathManager.getLogPath() + "/threadDumps-" + myDateFormat.format(new Date()) + "-" + ApplicationInfo.getInstance().getBuild().asString()); - myCurHangLogDir = myLogDir; + myCurHangLogDir = mySessionLogDir; try { myShutdownSemaphore.acquire(); @@ -164,22 +164,22 @@ public class PerformanceWatcher implements ApplicationComponent { } if (mySwingThreadCounter != myLoopCounter) { myUnresponsiveDuration += UNRESPONSIVE_INTERVAL; - if (myUnresponsiveDuration == UNRESPONSIVE_THRESHOLD) { - //System.out.println("EDT is not responding at " + myPrintDateFormat.format(new Date())); - myCurHangLogDir = new File(myLogDir, myDateFormat.format(new Date())); - } if (myUnresponsiveDuration >= UNRESPONSIVE_THRESHOLD) { + if (myCurHangLogDir == mySessionLogDir) { + //System.out.println("EDT is not responding at " + myPrintDateFormat.format(new Date())); + myCurHangLogDir = new File(mySessionLogDir, myDateFormat.format(new Date())); + } dumpThreads(false); } } else { if (myUnresponsiveDuration >= UNRESPONSIVE_THRESHOLD) { //System.out.println("EDT was unresponsive for " + myUnresponsiveDuration + " seconds"); - if (myCurHangLogDir.exists()) { - myCurHangLogDir.renameTo(new File(myLogDir, getLogDirForHang())); + if (myCurHangLogDir != mySessionLogDir && myCurHangLogDir.exists()) { + myCurHangLogDir.renameTo(new File(mySessionLogDir, getLogDirForHang())); } myUnresponsiveDuration = 0; - myCurHangLogDir = myLogDir; + myCurHangLogDir = mySessionLogDir; myStacktraceCommonPart = null; } diff --git a/platform/platform-impl/src/com/intellij/execution/impl/EditorHyperlinkSupport.java b/platform/platform-impl/src/com/intellij/execution/impl/EditorHyperlinkSupport.java index 26429fc0e896..d263288634b7 100644 --- a/platform/platform-impl/src/com/intellij/execution/impl/EditorHyperlinkSupport.java +++ b/platform/platform-impl/src/com/intellij/execution/impl/EditorHyperlinkSupport.java @@ -181,7 +181,8 @@ public class EditorHyperlinkSupport { new FilteringProcessor<RangeHighlighterEx>(new Condition<RangeHighlighterEx>() { @Override public boolean value(RangeHighlighterEx rangeHighlighterEx) { - return HYPERLINK_LAYER == rangeHighlighterEx.getLayer() && + return rangeHighlighterEx.getEditorFilter().avaliableIn(editor) && + HYPERLINK_LAYER == rangeHighlighterEx.getLayer() && rangeHighlighterEx.isValid() && getHyperlinkInfo(rangeHighlighterEx) != null; } diff --git a/platform/platform-impl/src/com/intellij/help/impl/KeymapGenerator.java b/platform/platform-impl/src/com/intellij/help/impl/KeymapGenerator.java index acd74f9c8f54..f38ef84a2b93 100644 --- a/platform/platform-impl/src/com/intellij/help/impl/KeymapGenerator.java +++ b/platform/platform-impl/src/com/intellij/help/impl/KeymapGenerator.java @@ -23,9 +23,11 @@ import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.keymap.ex.KeymapManagerEx; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import gnu.trove.THashSet; import java.io.File; import java.io.IOException; +import java.util.Set; /** * @author Konstantin Bulenkov @@ -47,13 +49,20 @@ public class KeymapGenerator implements ApplicationStarter { xml.append("<Keymaps>\n"); for (Keymap keymap : KeymapManagerEx.getInstanceEx().getAllKeymaps()) { - xml.append(" <Keymap name=\"").append(keymap.getName()).append("\">\n"); + + xml.append(" <Keymap name=\"").append(keymap.getPresentableName()).append("\">\n"); for (String id : keymap.getActionIds()) { String shortcuts = KeymapUtil.getShortcutsText(keymap.getShortcuts(id)); if (!StringUtil.isEmpty(shortcuts)) { xml.append(" <Action id=\"").append(id).append("\">\n"); + Set<String> addedShortcuts = new THashSet<String>(); for (Shortcut shortcut : keymap.getShortcuts(id)) { - xml.append(" <Shortcut>").append(KeymapUtil.getShortcutText(shortcut)).append("</Shortcut>\n"); + // Different shortcuts may have equal display strings (e.g. shift+minus and shift+subtract) + // We don't want them do be duplicated for users + String shortcutText = KeymapUtil.getShortcutText(shortcut); + if (addedShortcuts.add(shortcutText)) { + xml.append(" <Shortcut>").append(shortcutText).append("</Shortcut>\n"); + } } xml.append(" </Action>\n"); } diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index e92f80ffc95c..1bbd74984fcc 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -44,6 +44,7 @@ import com.intellij.util.ReflectionUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.UIUtil; +import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -53,6 +54,7 @@ import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.*; import java.util.List; @@ -731,9 +733,29 @@ public class IdeEventQueue extends EventQueue { } } + private static Field stickyAltField; //IDEA-17359 private static void fixStickyAlt(AWTEvent e) { - if (SystemInfo.isWindowsXP && e instanceof KeyEvent && ((KeyEvent)e).getKeyCode() == KeyEvent.VK_ALT) { + if (Registry.is("actionSystem.win.suppressAlt.new")) { + if (SystemInfo.isWindows + && UIManager.getLookAndFeel() instanceof WindowsLookAndFeel + && e instanceof InputEvent + && (((InputEvent)e).getModifiers() & (InputEvent.ALT_MASK | InputEvent.ALT_DOWN_MASK)) != 0 + && !(e instanceof KeyEvent && ((KeyEvent)e).getKeyCode() == KeyEvent.VK_ALT)) { + try { + if (stickyAltField == null) { + stickyAltField = Class + .forName("com.sun.java.swing.plaf.windows.WindowsRootPaneUI$AltProcessor") + .getDeclaredField("menuCanceledOnPress"); + stickyAltField.setAccessible(true); + } + stickyAltField.set(null, true); + } + catch (Exception exception) { + LOG.error(exception); + } + } + } else if (SystemInfo.isWindowsXP && e instanceof KeyEvent && ((KeyEvent)e).getKeyCode() == KeyEvent.VK_ALT) { ((KeyEvent)e).consume(); } } @@ -940,7 +962,7 @@ public class IdeEventQueue extends EventQueue { @Override public boolean dispatch(AWTEvent e) { boolean dispatch = true; - if (e instanceof KeyEvent) { + if (!Registry.is("actionSystem.win.suppressAlt.new") && e instanceof KeyEvent) { KeyEvent ke = (KeyEvent)e; final Component component = ke.getComponent(); final Window window = component == null ? null : SwingUtilities.windowForComponent(component); diff --git a/platform/platform-impl/src/com/intellij/ide/MacOSApplicationProvider.java b/platform/platform-impl/src/com/intellij/ide/MacOSApplicationProvider.java index 798c029e01a8..a90d0df033ff 100644 --- a/platform/platform-impl/src/com/intellij/ide/MacOSApplicationProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/MacOSApplicationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,8 +28,6 @@ import com.intellij.openapi.actionSystem.ex.ActionManagerEx; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.options.ShowSettingsUtil; -import com.intellij.openapi.options.ex.IdeConfigurablesGroup; -import com.intellij.openapi.options.ex.ProjectConfigurablesGroup; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.SystemInfo; @@ -98,8 +96,7 @@ public class MacOSApplicationProvider implements ApplicationComponent { } if (!((ShowSettingsUtilImpl)ShowSettingsUtil.getInstance()).isAlreadyShown()) { - ShowSettingsUtil.getInstance().showSettingsDialog(project, new ProjectConfigurablesGroup(project), - new IdeConfigurablesGroup()); + ShowSettingsUtil.getInstance().showSettingsDialog(project, ShowSettingsUtilImpl.getConfigurableGroups(project, true)); } applicationEvent.setHandled(true); } diff --git a/platform/platform-impl/src/com/intellij/ide/TipOfTheDayManager.java b/platform/platform-impl/src/com/intellij/ide/TipOfTheDayManager.java index 3c510c0a7ac8..a93fea76ca67 100644 --- a/platform/platform-impl/src/com/intellij/ide/TipOfTheDayManager.java +++ b/platform/platform-impl/src/com/intellij/ide/TipOfTheDayManager.java @@ -39,7 +39,7 @@ public class TipOfTheDayManager implements StartupActivity, DumbAware { ToolWindowManager.getInstance(project).invokeLater(new Runnable() { public void run() { if (project.isDisposed()) return; - new TipDialog().show(); + TipDialog.createForProject(project).show(); } }); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsAction.java index e89a7a328b28..eda6ec9f2d7c 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,6 @@ import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.options.ShowSettingsUtil; -import com.intellij.openapi.options.ex.IdeConfigurablesGroup; -import com.intellij.openapi.options.ex.ProjectConfigurablesGroup; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; @@ -60,7 +58,6 @@ public class ShowSettingsAction extends AnAction implements DumbAware { } } }); - ShowSettingsUtil.getInstance().showSettingsDialog(project, new ProjectConfigurablesGroup(project), - new IdeConfigurablesGroup()); + ShowSettingsUtil.getInstance().showSettingsDialog(project, ShowSettingsUtilImpl.getConfigurableGroups(project, true)); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java index 7e31726d5f97..4df11f7261ca 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.options.ex.ConfigurableExtensionPointUtil; import com.intellij.openapi.options.ex.IdeConfigurablesGroup; +import com.intellij.openapi.options.ex.MixedConfigurableGroup; import com.intellij.openapi.options.ex.ProjectConfigurablesGroup; import com.intellij.openapi.options.ex.SingleConfigurableEditor; import com.intellij.openapi.options.newEditor.OptionsEditor; @@ -29,6 +30,7 @@ import com.intellij.openapi.options.newEditor.OptionsEditorDialog; import com.intellij.openapi.options.newEditor.PreferencesDialog; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.registry.Registry; import com.intellij.util.ui.update.Activatable; import com.intellij.util.ui.update.UiNotifyConnector; @@ -47,11 +49,62 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.ShowSettingsUtilImpl"); private AtomicBoolean myShown = new AtomicBoolean(false); + @NotNull + private static Project getProject(@Nullable Project project) { + return project != null ? project : ProjectManager.getInstance().getDefaultProject(); + } + + @NotNull + private static DialogWrapper getDialog(@Nullable Project project, @NotNull ConfigurableGroup[] groups, @Nullable Configurable toSelect) { + return Registry.is("ide.perProjectModality") + ? new OptionsEditorDialog(getProject(project), filterEmptyGroups(groups), toSelect, true) + : Registry.is("ide.new.preferences") + ? new PreferencesDialog(getProject(project), filterEmptyGroups(groups)) + : new OptionsEditorDialog(getProject(project), filterEmptyGroups(groups), toSelect); + } + + @NotNull + public static ConfigurableGroup[] getConfigurableGroups(@Nullable Project project, boolean withIdeSettings) { + ConfigurableGroup[] groups = !withIdeSettings + ? new ConfigurableGroup[]{new ProjectConfigurablesGroup(getProject(project))} + : (project == null) + ? new ConfigurableGroup[]{new IdeConfigurablesGroup()} + : new ConfigurableGroup[]{ + new ProjectConfigurablesGroup(project), + new IdeConfigurablesGroup()}; + + return Registry.is("ide.file.settings.order.new") + ? MixedConfigurableGroup.getGroups(getConfigurables(groups, true)) + : groups; + } + + @NotNull + public static Configurable[] getConfigurables(@Nullable Project project, boolean withGroupReverseOrder) { + return getConfigurables(getConfigurableGroups(project, true), withGroupReverseOrder); + } + + @NotNull + private static Configurable[] getConfigurables(@NotNull ConfigurableGroup[] groups, boolean withGroupReverseOrder) { + Configurable[][] arrays = new Configurable[groups.length][]; + int length = 0; + for (int i = 0; i < groups.length; i++) { + arrays[i] = groups[withGroupReverseOrder ? groups.length - 1 - i : i].getConfigurables(); + length += arrays[i].length; + } + Configurable[] configurables = new Configurable[length]; + int offset = 0; + for (Configurable[] array : arrays) { + System.arraycopy(array, 0, configurables, offset, array.length); + offset += array.length; + } + return configurables; + } + @Override public void showSettingsDialog(@NotNull Project project, @NotNull ConfigurableGroup[] group) { try { myShown.set(true); - _showSettingsDialog(project, group, null); + getDialog(project, group, null).show(); } catch (Exception e) { LOG.error(e); @@ -61,41 +114,17 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil { } } - private static void _showSettingsDialog(@NotNull final Project project, @NotNull ConfigurableGroup[] group, @Nullable Configurable toSelect) { - group = filterEmptyGroups(group); - if (Registry.is("ide.perProjectModality")) { - new OptionsEditorDialog(project, group, toSelect, true).show(); - } else { - if (Registry.is("ide.new.preferences")) { - new PreferencesDialog(project, group).show(); - } else { - new OptionsEditorDialog(project, group, toSelect).show(); - } - } - } - @Override public void showSettingsDialog(@Nullable final Project project, final Class configurableClass) { assert Configurable.class.isAssignableFrom(configurableClass) : "Not a configurable: " + configurableClass.getName(); - ConfigurableGroup[] groups; - IdeConfigurablesGroup commonGroup = new IdeConfigurablesGroup(); - ProjectConfigurablesGroup projectGroup = project == null ? null : new ProjectConfigurablesGroup(project); - if (projectGroup == null) { - groups = new ConfigurableGroup[] {commonGroup}; - } else { - groups = new ConfigurableGroup[] {projectGroup, commonGroup}; - } + ConfigurableGroup[] groups = getConfigurableGroups(project, true); - Configurable config = findByClass(commonGroup.getConfigurables(), configurableClass); - if (config == null && projectGroup != null) { - config = findByClass(projectGroup.getConfigurables(), configurableClass); - } + Configurable config = findByClass(getConfigurables(groups, true), configurableClass); assert config != null : "Cannot find configurable: " + configurableClass.getName(); - @NotNull Project nnProject = project != null ? project : ProjectManager.getInstance().getDefaultProject(); - _showSettingsDialog(nnProject, groups, config); + getDialog(project, groups, config).show(); } @Nullable @@ -110,15 +139,9 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil { @Override public void showSettingsDialog(@Nullable final Project project, @NotNull final String nameToSelect) { - ConfigurableGroup[] group; - if (project == null) { - group = new ConfigurableGroup[]{new IdeConfigurablesGroup()}; - } - else { - group = new ConfigurableGroup[]{new ProjectConfigurablesGroup(project), new IdeConfigurablesGroup()}; - } + ConfigurableGroup[] group = getConfigurableGroups(project, true); - Project actualProject = project != null ? project : ProjectManager.getInstance().getDefaultProject(); + Project actualProject = getProject(project); group = filterEmptyGroups(group); @@ -133,15 +156,9 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil { } public static void showSettingsDialog(@Nullable Project project, final String id2Select, final String filter) { - ConfigurableGroup[] group; - if (project == null) { - group = new ConfigurableGroup[]{new IdeConfigurablesGroup()}; - } - else { - group = new ConfigurableGroup[]{new ProjectConfigurablesGroup(project), new IdeConfigurablesGroup()}; - } + ConfigurableGroup[] group = getConfigurableGroups(project, true); - Project actualProject = project != null ? project : ProjectManager.getInstance().getDefaultProject(); + Project actualProject = getProject(project); group = filterEmptyGroups(group); final Configurable configurable2Select = findConfigurable2Select(id2Select, group); @@ -191,10 +208,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil { @Override public void showSettingsDialog(@NotNull final Project project, final Configurable toSelect) { - _showSettingsDialog(project, new ConfigurableGroup[]{ - new ProjectConfigurablesGroup(project), - new IdeConfigurablesGroup() - }, toSelect); + getDialog(project, getConfigurableGroups(project, true), toSelect).show(); } @NotNull diff --git a/platform/platform-impl/src/com/intellij/ide/actions/TemplateProjectPropertiesAction.java b/platform/platform-impl/src/com/intellij/ide/actions/TemplateProjectPropertiesAction.java index 75657c517ecb..6c2b7d8e62f6 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/TemplateProjectPropertiesAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/TemplateProjectPropertiesAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package com.intellij.ide.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.options.ShowSettingsUtil; -import com.intellij.openapi.options.ex.ProjectConfigurablesGroup; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectManagerEx; @@ -26,6 +25,6 @@ import com.intellij.openapi.project.ex.ProjectManagerEx; public class TemplateProjectPropertiesAction extends AnAction implements DumbAware { public void actionPerformed(AnActionEvent e) { Project defaultProject = ProjectManagerEx.getInstanceEx().getDefaultProject(); - ShowSettingsUtil.getInstance().showSettingsDialog(defaultProject, new ProjectConfigurablesGroup(defaultProject)); + ShowSettingsUtil.getInstance().showSettingsDialog(defaultProject, ShowSettingsUtilImpl.getConfigurableGroups(defaultProject, false)); } } diff --git a/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java b/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java index de154f249c9e..930901d55105 100644 --- a/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java +++ b/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java @@ -17,6 +17,7 @@ package com.intellij.ide.customize; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.ide.plugins.RepositoryHelper; import com.intellij.idea.StartupUtil; import com.intellij.openapi.application.PathManager; @@ -58,14 +59,14 @@ class PluginGroups { } private PluginGroups() { - myAllPlugins = PluginManager.loadDescriptors(null); + myAllPlugins = PluginManagerCore.loadDescriptors(null); try { myPluginsFromRepository.addAll(RepositoryHelper.loadPluginsFromRepository(null)); } catch (Exception e) { //OK, it's offline } - PluginManager.loadDisabledPlugins(new File(PathManager.getConfigPath()).getPath(), myDisabledPluginIds); + PluginManagerCore.loadDisabledPlugins(new File(PathManager.getConfigPath()).getPath(), myDisabledPluginIds); myTree.put(CORE, Pair.create((String)null, Arrays.asList( @@ -74,7 +75,6 @@ class PluginGroups { "org.intellij.intelliLang", "com.intellij.properties", "Refactor-X",//? - "Structural Search", "Type Migration", "ZKM" ))); diff --git a/platform/platform-impl/src/com/intellij/ide/file/BatchFileChangeListener.java b/platform/platform-impl/src/com/intellij/ide/file/BatchFileChangeListener.java new file mode 100644 index 000000000000..593c39885a46 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/file/BatchFileChangeListener.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.file; + +import com.intellij.openapi.project.Project; +import com.intellij.util.messages.Topic; + +/** + * This listener is notified when some operation performs a massive batch file change, and when this change is completed. + * <p/> + * To subscribe to such batch file changes, connect to the Project's {@link com.intellij.util.messages.MessageBus} + * via the {@link #TOPIC} defined below. + */ +public interface BatchFileChangeListener { + + Topic<BatchFileChangeListener> TOPIC = Topic.create("Batch File Update", BatchFileChangeListener.class); + + class Adapter implements BatchFileChangeListener { + @Override + public void batchChangeStarted(Project project) { + } + @Override + public void batchChangeCompleted(Project project) { + } + } + + + void batchChangeStarted(Project project); + + void batchChangeCompleted(Project project); + +} diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/HelpID.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/HelpID.java index b05021ff7d72..a805638501be 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/HelpID.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/HelpID.java @@ -24,6 +24,8 @@ import org.jetbrains.annotations.NonNls; * Time: 2:09 PM */ public interface HelpID { - @NonNls String RESET_PASSWORD = "reference_ide_settings_master_password_reset"; - @NonNls String CHANGE_PASSWORD = "reference_settings_password_safe_master_password"; + @NonNls String INIT_PASSWORD = "settings_passwords_master_password_init"; + @NonNls String ENTER_PASSWORD = "settings_passwords_master_password_enter"; + @NonNls String RESET_PASSWORD = "settings_passwords_master_password_reset"; + @NonNls String CHANGE_PASSWORD = "settings_passwords_master_password_change"; } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java index b1ea1332986e..e5b9f1530256 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java @@ -25,15 +25,21 @@ import org.jetbrains.annotations.Nullable; * The interface defines basic password management operations */ public interface PasswordStorage { + /** - * <p>Get password stored in a password safe.</p> - * - * <p><b>NB: </b> - * This method may be called from the background, - * and it may need to ask user to enter the master password to access the database by calling - * {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()} to show a modal dialog. - * So make sure not to call it from the read action. - * Calling this method from the dispatch thread is allowed.</p> + * @deprecated To remove in IDEA 15. Use {@link #getPassword(Project, Class, String, ModalityState)} + */ + @Deprecated + @Nullable + String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException; + + /** + * Get password stored in a password safe. + * <p/> + * The method may be called from any thread. It may need to show a master password dialog to unlock the password database, + * and then will use {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()}. + * So make sure to pass correct {@link ModalityState} to the method to make sure the dialog is shown above all other dialog or progress + * windows. * * @param project the project, that is used to ask for the master password if this is the first access to password safe * @param requestor the requestor class @@ -43,25 +49,53 @@ public interface PasswordStorage { * @throws IllegalStateException if the method is called from the read action. */ @Nullable - String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException; + String getPassword(@Nullable Project project, @NotNull Class requestor, String key, + @Nullable ModalityState state) throws PasswordSafeException; + /** - * Remove password stored in a password safe + * Store password in password safe + * <p/> + * The method may be called from any thread. It may need to show a master password dialog to unlock the password database, + * and then will use {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()}. + * So make sure to pass correct {@link ModalityState} to the method to make sure the dialog is shown above all other dialog or progress + * windows. * * @param project the project, that is used to ask for the master password if this is the first access to password safe * @param requestor the requestor class * @param key the key for the password - * @return the plugin key + * @param value the value to store * @throws PasswordSafeException if password safe cannot be accessed */ + void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value, + @Nullable ModalityState modalityState) throws PasswordSafeException; + + /** + * @deprecated To remove in IDEA 15. Use {@link #storePassword(Project, Class, String, String, ModalityState)} + */ + @Deprecated + void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException; + + /** + * @deprecated To remove in IDEA 15. Use {@link #removePassword(Project, Class, String, ModalityState)} + */ + @Deprecated void removePassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException; + /** - * Store password in password safe + * Remove password stored in a password safe + * <p/> + * The method may be called from any thread. It may need to show a master password dialog to unlock the password database, + * and then will use {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()}. + * So make sure to pass correct {@link ModalityState} to the method to make sure the dialog is shown above all other dialog or progress + * windows. * * @param project the project, that is used to ask for the master password if this is the first access to password safe * @param requestor the requestor class * @param key the key for the password - * @param value the value to store + * @return the plugin key * @throws PasswordSafeException if password safe cannot be accessed */ - void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException; + void removePassword(@Nullable Project project, @NotNull Class requestor, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException; + } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java index 11dc4d7d018b..34aee7aaad38 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java @@ -22,42 +22,19 @@ import com.intellij.ide.passwordSafe.impl.providers.masterKey.MasterKeyPasswordS import com.intellij.ide.passwordSafe.impl.providers.masterKey.PasswordDatabase; import com.intellij.ide.passwordSafe.impl.providers.memory.MemoryPasswordSafe; import com.intellij.ide.passwordSafe.impl.providers.nil.NilProvider; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -/** - * The implementation of password safe service - */ public class PasswordSafeImpl extends PasswordSafe { - /** - * The logger instance - */ private static final Logger LOG = Logger.getInstance(PasswordSafeImpl.class.getName()); - /** - * The current settings - */ private final PasswordSafeSettings mySettings; - /** - * The master key provider - */ private final MasterKeyPasswordSafe myMasterKeyProvider; - /** - * The nil provider - */ private final NilProvider myNilProvider; - /** - * The memory provider - */ private final MemoryPasswordSafe myMemoryProvider; - /** - * The constructor - * - * @param settings the settings for the password safe - * @param database the password database - */ public PasswordSafeImpl(PasswordSafeSettings settings, PasswordDatabase database) { mySettings = settings; myMasterKeyProvider = new MasterKeyPasswordSafe(database); @@ -89,21 +66,24 @@ public class PasswordSafeImpl extends PasswordSafe { return p; } - - /** - * @return settings for the passwords safe - */ public PasswordSafeSettings getSettings() { return mySettings; } - @Nullable + @Override public String getPassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException { + return getPassword(project, requester, key, null); + } + + @Nullable + @Override + public String getPassword(@Nullable Project project, @NotNull Class requester, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { if (mySettings.getProviderType().equals(PasswordSafeSettings.ProviderType.MASTER_PASSWORD)) { - String password = getMemoryProvider().getPassword(project, requester, key); + String password = getMemoryProvider().getPassword(project, requester, key, modalityState); if (password == null) { - password = provider().getPassword(project, requester, key); + password = provider().getPassword(project, requester, key, modalityState); if (password != null) { // cache the password in memory as well for easier access during the session getMemoryProvider().storePassword(project, requester, key, password); @@ -111,27 +91,35 @@ public class PasswordSafeImpl extends PasswordSafe { } return password; } - return provider().getPassword(project, requester, key); + return provider().getPassword(project, requester, key, modalityState); } - /** - * {@inheritDoc} - */ - public void removePassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException { + @Override + public void removePassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException { + removePassword(project, requestor, key, null); + } + + @Override + public void removePassword(@Nullable Project project, @NotNull Class requester, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { if (mySettings.getProviderType().equals(PasswordSafeSettings.ProviderType.MASTER_PASSWORD)) { getMemoryProvider().removePassword(project, requester, key); } - provider().removePassword(project, requester, key); + provider().removePassword(project, requester, key, modalityState); } - /** - * {@inheritDoc} - */ - public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value) throws PasswordSafeException { + @Override + public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException { + storePassword(project, requestor, key, value, null); + } + + @Override + public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value, + @Nullable ModalityState modalityState) throws PasswordSafeException { if (mySettings.getProviderType().equals(PasswordSafeSettings.ProviderType.MASTER_PASSWORD)) { getMemoryProvider().storePassword(project, requester, key, value); } - provider().storePassword(project, requester, key, value); + provider().storePassword(project, requester, key, value, modalityState); } /** diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java index 18dee7c755f5..3a40d617e99b 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java @@ -15,7 +15,11 @@ */ package com.intellij.ide.passwordSafe.impl; +import com.intellij.ide.passwordSafe.PasswordSafeException; import com.intellij.ide.passwordSafe.PasswordStorage; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * The provider for password safe component @@ -34,4 +38,21 @@ public abstract class PasswordSafeProvider implements PasswordStorage { * @return the name of provider */ public abstract String getName(); + + @Nullable + @Override + public String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException { + return getPassword(project, requestor, key, null); + } + + @Override + public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException { + storePassword(project, requestor, key, value, null); + } + + @Override + public void removePassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException { + removePassword(project, requestor, key, null); + } + } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java index c72c65d0d528..8c8f921f18b8 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java @@ -43,16 +43,15 @@ public abstract class BasePasswordSafeProvider extends PasswordSafeProvider { * @throws PasswordSafeException in case of problems with access to the password database. * @throws IllegalStateException if the method is called from the read action. */ - protected abstract byte[] key(@Nullable Project project, @NotNull Class requestor) throws PasswordSafeException; + protected abstract byte[] key(@Nullable Project project, @NotNull Class requestor, + @Nullable ModalityState modalityState) throws PasswordSafeException; - /** - * {@inheritDoc} - */ @Nullable - public String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException { - byte[] k = dbKey(project, requestor, key); + public String getPassword(@Nullable Project project, @NotNull Class requestor, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { + byte[] k = dbKey(project, requestor, key, modalityState); byte[] ct = getEncryptedPassword(k); - return ct == null ? null : EncryptionUtil.decryptText(key(project, requestor), ct); + return ct == null ? null : EncryptionUtil.decryptText(key(project, requestor, modalityState), ct); } /** @@ -69,17 +68,17 @@ public abstract class BasePasswordSafeProvider extends PasswordSafeProvider { * @param project * @param requestor the requestor class * @param key the key to use + * @param modalityState * @return the key to use for map */ - private byte[] dbKey(@Nullable Project project, Class requestor, String key) throws PasswordSafeException { - return EncryptionUtil.dbKey(key(project, requestor), requestor, key); + private byte[] dbKey(@Nullable Project project, @NotNull Class requestor, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { + return EncryptionUtil.dbKey(key(project, requestor, modalityState), requestor, key); } - /** - * {@inheritDoc} - */ - public void removePassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException { - byte[] k = dbKey(project, requester, key); + public void removePassword(@Nullable Project project, @NotNull Class requester, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { + byte[] k = dbKey(project, requester, key, modalityState); removeEncryptedPassword(k); } @@ -90,12 +89,10 @@ public abstract class BasePasswordSafeProvider extends PasswordSafeProvider { */ protected abstract void removeEncryptedPassword(byte[] key); - /** - * {@inheritDoc} - */ - public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException { - byte[] k = dbKey(project, requestor, key); - byte[] ct = EncryptionUtil.encryptText(key(project, requestor), value); + public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value, + @Nullable ModalityState modalityState) throws PasswordSafeException { + byte[] k = dbKey(project, requestor, key, modalityState); + byte[] ct = EncryptionUtil.encryptText(key(project, requestor, modalityState), value); storeEncryptedPassword(k, ct); } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/EnterPasswordComponent.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/EnterPasswordComponent.java index 638e2e23c1f9..304b31e3bee1 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/EnterPasswordComponent.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/EnterPasswordComponent.java @@ -16,6 +16,7 @@ package com.intellij.ide.passwordSafe.impl.providers.masterKey; import com.intellij.ide.TypePresentationService; +import com.intellij.ide.passwordSafe.HelpID; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -46,4 +47,9 @@ public class EnterPasswordComponent extends PasswordComponentBase { String password = new String(myPasswordField.getPassword()); return mySafe.changeMasterPassword(password, password, myEncryptCheckBox.isSelected()); } + + @Override + public String getHelpId() { + return HelpID.ENTER_PASSWORD; + } } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java index 95fba48afabe..b74e51315cd5 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java @@ -42,17 +42,8 @@ import java.util.concurrent.atomic.AtomicReference; * The password safe that stores information in configuration file encrypted by master password */ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { - /** - * The test password key - */ private static final String TEST_PASSWORD_KEY = "TEST_PASSWORD:"; - /** - * The test password value - */ private static final String TEST_PASSWORD_VALUE = "test password"; - /** - * The password database instance - */ final PasswordDatabase database; /** * The key to use to encrypt data @@ -68,18 +59,10 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { } }; - /** - * The constructor - * - * @param database the password database - */ public MasterKeyPasswordSafe(PasswordDatabase database) { this.database = database; } - /** - * @return true if the component is running in the test mode - */ protected boolean isTestMode() { return false; } @@ -130,7 +113,6 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { else { return true; } - } /** @@ -167,18 +149,13 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { } - /** - * The test key - * - * @param password the password for the test key - * @return the test key - */ private static String testKey(String password) { return TEST_PASSWORD_KEY + password; } @Override - protected byte[] key(@Nullable final Project project, @NotNull final Class requestor) throws PasswordSafeException { + protected byte[] key(@Nullable final Project project, @NotNull final Class requestor, + @Nullable ModalityState modalityState) throws PasswordSafeException { Application application = ApplicationManager.getApplication(); if (!isTestMode() && application.isHeadlessEnvironment()) { throw new MasterPasswordUnavailableException("The provider is not available in headless environment"); @@ -223,7 +200,7 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { } } } - }, ModalityState.defaultModalityState()); + }, modalityState == null ? ModalityState.defaultModalityState() : modalityState); //noinspection ThrowableResultOfMethodCallIgnored if (ex.get() != null) { throw ex.get(); @@ -233,20 +210,15 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { return result.get(); } - /** - * {@inheritDoc} - */ @Override - public String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException { + public String getPassword(@Nullable Project project, @NotNull Class requestor, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { if (database.isEmpty()) { return null; } - return super.getPassword(project, requestor, key); + return super.getPassword(project, requestor, key, modalityState); } - /** - * {@inheritDoc} - */ @Override public void removePassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException { if (database.isEmpty()) { @@ -255,50 +227,32 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { super.removePassword(project, requester, key); } - /** - * {@inheritDoc} - */ @Override protected byte[] getEncryptedPassword(byte[] key) { return database.get(key); } - /** - * {@inheritDoc} - */ @Override protected void removeEncryptedPassword(byte[] key) { database.remove(key); } - /** - * {@inheritDoc} - */ @Override protected void storeEncryptedPassword(byte[] key, byte[] encryptedPassword) { database.put(key, encryptedPassword); } - /** - * {@inheritDoc} - */ @Override public boolean isSupported() { return !ApplicationManager.getApplication().isHeadlessEnvironment(); } - /** - * {@inheritDoc} - */ @Override public String getDescription() { return "This provider stores passwords in IDEA config and uses master password to encrypt other passwords. " + "The passwords for the same resources are shared between different projects."; } - /** - * {@inheritDoc} - */ @Override public String getName() { return "Master Key PasswordSafe"; @@ -309,9 +263,6 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { return setMasterPassword(""); } - /** - * @return true, if OS protected passwords are supported for the current platform - */ @SuppressWarnings({"MethodMayBeStatic"}) public boolean isOsProtectedPasswordSupported() { // TODO extension point needed? @@ -351,9 +302,6 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { } } - /** - * @return true, if the password is currently encrypted in the database - */ public boolean isPasswordEncrypted() { if (!isOsProtectedPasswordSupported()) return false; @@ -361,9 +309,6 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider { return i != null && i.length > 0; } - /** - * @return check if provider database is empty - */ public boolean isEmpty() { return database.isEmpty(); } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/ResetPasswordComponent.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/ResetPasswordComponent.java index ce75bdb2165a..faa36c121ec9 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/ResetPasswordComponent.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/ResetPasswordComponent.java @@ -49,7 +49,7 @@ public class ResetPasswordComponent extends PasswordComponentBase { @Override public String getHelpId() { - return HelpID.RESET_PASSWORD; + return myFirstTime ? HelpID.INIT_PASSWORD : HelpID.RESET_PASSWORD; } @Override diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java index 5be4a25df859..da82bb986fdb 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java @@ -19,10 +19,12 @@ import com.intellij.ide.passwordSafe.impl.PasswordSafeTimed; import com.intellij.ide.passwordSafe.impl.providers.BasePasswordSafeProvider; import com.intellij.ide.passwordSafe.impl.providers.ByteArrayWrapper; import com.intellij.ide.passwordSafe.impl.providers.EncryptionUtil; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.registry.Registry; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.security.SecureRandom; import java.util.Collections; @@ -57,13 +59,8 @@ public class MemoryPasswordSafe extends BasePasswordSafeProvider { return Registry.intValue("passwordSafe.memorySafe.ttl"); } - /** - * @param project the project to use - * @param requestor - * @return the secret key used by provider - */ @Override - protected byte[] key(Project project, @NotNull Class requestor) { + protected byte[] key(Project project, @NotNull Class requestor, @Nullable ModalityState modalityState) { if (key.get() == null) { byte[] rnd = new byte[EncryptionUtil.SECRET_KEY_SIZE_BYTES * 16]; new SecureRandom().nextBytes(rnd); @@ -72,49 +69,31 @@ public class MemoryPasswordSafe extends BasePasswordSafeProvider { return key.get(); } - /** - * {@inheritDoc} - */ @Override protected byte[] getEncryptedPassword(byte[] key) { return database.get().get(new ByteArrayWrapper(key)); } - /** - * {@inheritDoc} - */ @Override protected void removeEncryptedPassword(byte[] key) { database.get().remove(new ByteArrayWrapper(key)); } - /** - * {@inheritDoc} - */ @Override protected void storeEncryptedPassword(byte[] key, byte[] encryptedPassword) { database.get().put(new ByteArrayWrapper(key), encryptedPassword); } - /** - * {@inheritDoc} - */ @Override public boolean isSupported() { return true; } - /** - * {@inheritDoc} - */ @Override public String getDescription() { return "Memory-based password safe provider. The passwords are stored only for the duration of IDEA process."; } - /** - * {@inheritDoc} - */ @Override public String getName() { return "Memory PasswordSafe"; diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java index 581df18ea317..e3a77325b06e 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java @@ -17,6 +17,7 @@ package com.intellij.ide.passwordSafe.impl.providers.nil; import com.intellij.ide.passwordSafe.PasswordSafeException; import com.intellij.ide.passwordSafe.impl.PasswordSafeProvider; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,49 +26,38 @@ import org.jetbrains.annotations.Nullable; * The most secure provider that does not store anything, so it cannot be cracked */ public final class NilProvider extends PasswordSafeProvider { - /** - * {@inheritDoc} - */ + @Override public boolean isSupported() { return true; } - /** - * {@inheritDoc} - */ @Override public String getDescription() { return "The provider that does not remembers password."; } - /** - * {@inheritDoc} - */ @Override public String getName() { return "Do not Store"; } - /** - * {@inheritDoc} - */ - public String getPassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException { + @Nullable + public String getPassword(@Nullable Project project, @NotNull Class requester, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { // nothing is stored return null; } - /** - * {@inheritDoc} - */ - public void removePassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException { + @Override + public void removePassword(@Nullable Project project, @NotNull Class requester, String key, + @Nullable ModalityState modalityState) throws PasswordSafeException { // do nothing } - /** - * {@inheritDoc} - */ - public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value) throws PasswordSafeException { + @Override + public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value, + @Nullable ModalityState modalityState) throws PasswordSafeException { // just forget about password } } diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java index def7aa96ce9b..353e836f3f33 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java @@ -176,7 +176,7 @@ public class PasswordSafePromptDialog extends DialogWrapper { ps.removePassword(project, requestor, key); } else { - String pw = ps.getPassword(project, requestor, key); + String pw = ps.getPassword(project, requestor, key, modalityState); if (pw != null) { return pw; } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java index 7919d1f894d0..b093773bc0fb 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java @@ -159,33 +159,35 @@ public class PluginInstaller { } } - synchronized (myLock) { - PluginDownloader downloader = null; - final String repositoryName = pluginNode.getRepositoryName(); - if (repositoryName != null) { - try { - final Map<PluginId, PluginDownloader> downloaders = new HashMap<PluginId, PluginDownloader>(); - if (!UpdateChecker.checkPluginsHost(repositoryName, downloaders)) { - return false; - } - downloader = downloaders.get(pluginNode.getPluginId()); - if (downloader == null) return false; - } - catch (Exception e) { + PluginDownloader downloader = null; + final String repositoryName = pluginNode.getRepositoryName(); + if (repositoryName != null) { + try { + final Map<PluginId, PluginDownloader> downloaders = new HashMap<PluginId, PluginDownloader>(); + if (!UpdateChecker.checkPluginsHost(repositoryName, downloaders)) { return false; } + downloader = downloaders.get(pluginNode.getPluginId()); + if (downloader == null) return false; } - else { - downloader = PluginDownloader.createDownloader(pluginNode); + catch (Exception e) { + return false; } - if (downloader.prepareToInstall(ProgressManager.getInstance().getProgressIndicator())) { + } + else { + downloader = PluginDownloader.createDownloader(pluginNode); + } + + if (downloader.prepareToInstall(ProgressManager.getInstance().getProgressIndicator())) { + synchronized (myLock) { downloader.install(); - pluginNode.setStatus(PluginNode.STATUS_DOWNLOADED); - } - else { - return false; } + pluginNode.setStatus(PluginNode.STATUS_DOWNLOADED); + } + else { + return false; } + return true; } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java index 49b20d27a585..20a41e3a886a 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java @@ -49,6 +49,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.*; import com.intellij.ui.border.CustomLineBorder; import com.intellij.ui.components.JBLabel; +import com.intellij.ui.speedSearch.SpeedSearchSupply; import com.intellij.util.concurrency.SwingWorker; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.update.UiNotifyConnector; @@ -663,7 +664,7 @@ public abstract class PluginManagerMain implements Disposable { app.restart(true); } else { - app.exit(true); + app.exit(false, true); } } }).notify(project); @@ -676,6 +677,7 @@ public abstract class PluginManagerMain implements Disposable { } public void filter() { + getPluginTable().putClientProperty(SpeedSearchSupply.SEARCH_QUERY_KEY, getFilter()); pluginsModel.filter(getFilter().toLowerCase()); TableUtil.ensureSelectionExists(getPluginTable()); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.form b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.form index 2e09735db57f..1791089faf85 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.form +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.form @@ -69,13 +69,11 @@ <size top="0" left="0" bottom="2" right="0"/> </border> <children> - <component id="a5e28" class="com.intellij.ui.components.JBLabel" binding="myName"> + <component id="edd99" class="com.intellij.ui.SimpleColoredComponent" binding="myName"> <constraints> <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> - <properties> - <text value="Plugin Name"/> - </properties> + <properties/> </component> </children> </grid> diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java index be7fd44fb7cc..c90306210856 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java @@ -23,10 +23,16 @@ import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.FileStatus; +import com.intellij.psi.codeStyle.NameUtil; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.speedSearch.SpeedSearchSupply; +import com.intellij.ui.speedSearch.SpeedSearchUtil; import com.intellij.util.Function; import com.intellij.util.text.DateFormatUtil; +import com.intellij.util.text.Matcher; import com.intellij.util.ui.UIUtil; import javax.swing.*; @@ -40,7 +46,7 @@ import java.util.Set; * @author Konstantin Bulenkov */ public class PluginsTableRenderer extends DefaultTableCellRenderer { - private JLabel myName; + private SimpleColoredComponent myName; private JLabel myStatus; private RatesPanel myRating; private JLabel myDownloads; @@ -85,7 +91,23 @@ public class PluginsTableRenderer extends DefaultTableCellRenderer { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (myPluginDescriptor != null) { final PluginId pluginId = myPluginDescriptor.getPluginId(); - myName.setText(myPluginDescriptor.getName() + " "); + myName.clear(); + myName.setOpaque(false); + String pluginName = myPluginDescriptor.getName() + " "; + Object query = table.getClientProperty(SpeedSearchSupply.SEARCH_QUERY_KEY); + if (query instanceof String) { + String pattern = "*" + query; + Matcher matcher = NameUtil.buildMatcher(pattern, 0, true, true, pattern.toLowerCase().equals(pattern)); + SimpleTextAttributes attr = new SimpleTextAttributes(UIUtil.getListBackground(isSelected), + UIUtil.getListForeground(isSelected), + JBColor.RED, + SimpleTextAttributes.STYLE_PLAIN); + + SpeedSearchUtil.appendColoredFragmentForMatcher(pluginName, myName, attr, matcher, + UIUtil.getTableBackground(isSelected), true); + } else { + myName.append(pluginName); + } final Color fg = UIUtil.getTableForeground(isSelected); final Color bg = UIUtil.getTableBackground(isSelected); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java b/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java index 0a7b70e07616..8febc9ad392a 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,12 @@ package com.intellij.ide.ui.search; import com.intellij.application.options.SkipSelfSearchComponent; +import com.intellij.ide.actions.ShowSettingsUtilImpl; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableGroup; import com.intellij.openapi.options.MasterDetails; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.options.ex.GlassPanel; -import com.intellij.openapi.options.ex.IdeConfigurablesGroup; -import com.intellij.openapi.options.ex.ProjectConfigurablesGroup; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; @@ -66,8 +65,7 @@ public class SearchUtil { } public static void processProjectConfigurables(Project project, HashMap<SearchableConfigurable, TreeSet<OptionDescription>> options) { - processConfigurables(new ProjectConfigurablesGroup(project).getConfigurables(), options); - processConfigurables(new IdeConfigurablesGroup().getConfigurables(), options); + processConfigurables(ShowSettingsUtilImpl.getConfigurables(project, false), options); } private static void processConfigurables(final Configurable[] configurables, diff --git a/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java b/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java deleted file mode 100644 index a743569b1798..000000000000 --- a/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.ide.util; - -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.util.text.StringUtil; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; - -import java.util.LinkedHashMap; -import java.util.Map; - -public class PropertiesComponentImpl extends PropertiesComponent implements PersistentStateComponent<Element> { - private final Map<String, String> myMap = new LinkedHashMap<String, String>(); - @NonNls private static final String ELEMENT_PROPERTY = "property"; - @NonNls private static final String ATTRIBUTE_NAME = "name"; - @NonNls private static final String ATTRIBUTE_VALUE = "value"; - - @NotNull - public String getComponentName() { - return "PropertiesComponent"; - } - - PropertiesComponentImpl() { - } - - @Override - public Element getState() { - Element parentNode = new Element("state"); - for (final String key : myMap.keySet()) { - String value = myMap.get(key); - if (value != null) { - Element element = new Element(ELEMENT_PROPERTY); - element.setAttribute(ATTRIBUTE_NAME, key); - element.setAttribute(ATTRIBUTE_VALUE, value); - parentNode.addContent(element); - } - } - return parentNode; - } - - @Override - public void loadState(final Element parentNode) { - myMap.clear(); - for (Element e : parentNode.getChildren(ELEMENT_PROPERTY)) { - String name = e.getAttributeValue(ATTRIBUTE_NAME); - if (name != null) { - myMap.put(name, e.getAttributeValue(ATTRIBUTE_VALUE)); - } - } - } - - @Override - public String getValue(String name) { - return myMap.get(name); - } - - @Override - public void setValue(String name, String value) { - myMap.put(name, value); - } - - @Override - public void setValue(@NotNull String name, @NotNull String value, @NotNull String defaultValue) { - if (value.equals(defaultValue)) { - myMap.remove(name); - } - else { - myMap.put(name, value); - } - } - - @Override - public void unsetValue(String name) { - myMap.remove(name); - } - - @Override - public boolean isValueSet(String name) { - return myMap.containsKey(name); - } - - @Override - public String[] getValues(@NonNls String name) { - final String value = getValue(name); - return value != null ? value.split("\n") : null; - } - - @Override - public void setValues(@NonNls String name, String[] values) { - if (values == null) { - setValue(name, null); - } - else { - setValue(name, StringUtil.join(values, "\n")); - } - } -}
\ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/util/TipDialog.java b/platform/platform-impl/src/com/intellij/ide/util/TipDialog.java index 33501b503477..0744e377e6c5 100644 --- a/platform/platform-impl/src/com/intellij/ide/util/TipDialog.java +++ b/platform/platform-impl/src/com/intellij/ide/util/TipDialog.java @@ -19,32 +19,44 @@ package com.intellij.ide.util; import com.intellij.CommonBundle; import com.intellij.ide.IdeBundle; import com.intellij.internal.statistic.UsageTrigger; +import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.impl.DialogWrapperPeerImpl; +import com.intellij.openapi.wm.ex.WindowManagerEx; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; public class TipDialog extends DialogWrapper{ - private final TipPanel myTipPanel; + private TipPanel myTipPanel; public TipDialog(){ - super(true); - setModal(false); - setTitle(IdeBundle.message("title.tip.of.the.day")); - setCancelButtonText(CommonBundle.getCloseButtonText()); - myTipPanel = new TipPanel(); - myTipPanel.nextTip(); - setHorizontalStretch(1.33f); - setVerticalStretch(1.25f); - init(); - if (getPeer() instanceof DialogWrapperPeerImpl) { - ((DialogWrapperPeerImpl)getPeer()).setAutoRequestFocus(false); - } + super(WindowManagerEx.getInstanceEx().findVisibleFrame(), true); + initialize(); + } + + public TipDialog(@NotNull final Window parent) { + super(parent, true); + initialize(); } + private void initialize () { + setModal(false); + setTitle(IdeBundle.message("title.tip.of.the.day")); + setCancelButtonText(CommonBundle.getCloseButtonText()); + myTipPanel = new TipPanel(); + myTipPanel.nextTip(); + setHorizontalStretch(1.33f); + setVerticalStretch(1.25f); + init(); + if (getPeer() instanceof DialogWrapperPeerImpl) { + ((DialogWrapperPeerImpl)getPeer()).setAutoRequestFocus(false); + } + } + @NotNull protected Action[] createActions(){ return new Action[]{new PreviousTipAction(),new NextTipAction(),getCancelAction()}; @@ -58,6 +70,11 @@ public class TipDialog extends DialogWrapper{ super.dispose(); } + public static TipDialog createForProject(final Project project) { + final Window w = WindowManagerEx.getInstanceEx().suggestParentWindow(project); + return (w == null) ? new TipDialog() : new TipDialog(w); + } + private class PreviousTipAction extends AbstractAction{ public PreviousTipAction(){ super(IdeBundle.message("action.previous.tip")); diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java b/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java index 3a8f73348640..67a7c0f88532 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java +++ b/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java @@ -199,7 +199,7 @@ public class IdeaLogger extends Logger { @Override public String getInfo() { final ApplicationInfoEx info = ApplicationInfoImpl.getShadowInstance(); - return info.getFullApplicationName() + " " + "Build #" + info.getBuild().asString(); + return info.getFullApplicationName() + " " + "Build #" + info.getBuild().asStringWithAllDetails(); } }; } diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java index 611e1a6ba607..10f9c7365cfe 100644 --- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java +++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java @@ -319,7 +319,7 @@ public class StartupUtil { ApplicationInfo appInfo = ApplicationInfoImpl.getShadowInstance(); ApplicationNamesInfo namesInfo = ApplicationNamesInfo.getInstance(); String buildDate = new SimpleDateFormat("dd MMM yyyy HH:ss", Locale.US).format(appInfo.getBuildDate().getTime()); - log.info("IDE: " + namesInfo.getFullProductName() + " (build #" + appInfo.getBuild() + ", " + buildDate + ")"); + log.info("IDE: " + namesInfo.getFullProductName() + " (build #" + appInfo.getBuild().asStringWithAllDetails() + ", " + buildDate + ")"); log.info("OS: " + SystemInfoRt.OS_NAME + " (" + SystemInfoRt.OS_VERSION + ", " + SystemInfo.OS_ARCH + ")"); log.info("JRE: " + System.getProperty("java.runtime.version", "-") + " (" + System.getProperty("java.vendor", "-") + ")"); log.info("JVM: " + System.getProperty("java.vm.version", "-") + " (" + System.getProperty("java.vm.name", "-") + ")"); diff --git a/platform/platform-impl/src/com/intellij/jps/impl/JpsIdePluginManagerImpl.java b/platform/platform-impl/src/com/intellij/jps/impl/JpsIdePluginManagerImpl.java index 72e7b8a4973e..a4d4637fa81d 100644 --- a/platform/platform-impl/src/com/intellij/jps/impl/JpsIdePluginManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/jps/impl/JpsIdePluginManagerImpl.java @@ -37,15 +37,26 @@ public class JpsIdePluginManagerImpl extends JpsPluginManager { public JpsIdePluginManagerImpl() { ExtensionsArea rootArea = Extensions.getRootArea(); - //todo[nik] introduce more generic platform extension for JPS plugins instead + //todo[nik] get rid of this check: currently this class is used in jps-builders tests instead of JpsPluginManagerImpl because platform-impl module is added to classpath via testFramework + if (rootArea.hasExtensionPoint(JpsPluginBean.EP_NAME.getName())) { + rootArea.getExtensionPoint(JpsPluginBean.EP_NAME).addExtensionPointListener(new ExtensionPointListener<JpsPluginBean>() { + @Override + public void extensionAdded(@NotNull JpsPluginBean extension, @Nullable PluginDescriptor pluginDescriptor) { + ContainerUtil.addIfNotNull(pluginDescriptor, myExternalBuildPlugins); + } + + @Override + public void extensionRemoved(@NotNull JpsPluginBean extension, @Nullable PluginDescriptor pluginDescriptor) { + } + }); + } if (rootArea.hasExtensionPoint("com.intellij.compileServer.plugin")) { ExtensionPoint extensionPoint = rootArea.getExtensionPoint("com.intellij.compileServer.plugin"); + //noinspection unchecked extensionPoint.addExtensionPointListener(new ExtensionPointListener() { @Override public void extensionAdded(@NotNull Object extension, @Nullable PluginDescriptor pluginDescriptor) { - if (pluginDescriptor != null) { - myExternalBuildPlugins.add(pluginDescriptor); - } + ContainerUtil.addIfNotNull(pluginDescriptor, myExternalBuildPlugins); } @Override diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java b/platform/platform-impl/src/com/intellij/jps/impl/JpsPluginBean.java index b3d3b35b5aa2..4979dd78cfe6 100644 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteInterpreterException.java +++ b/platform/platform-impl/src/com/intellij/jps/impl/JpsPluginBean.java @@ -13,17 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.remotesdk; +package com.intellij.jps.impl; -import com.intellij.remote.RemoteSdkException; +import com.intellij.openapi.extensions.AbstractExtensionPointBean; +import com.intellij.openapi.extensions.ExtensionPointName; /** - * @deprecated Remove in IDEA 14 - * - * @author traff + * @author nik */ -public class RemoteInterpreterException extends RemoteSdkException { - public RemoteInterpreterException(String s, Throwable throwable) { - super(s, throwable); - } +public class JpsPluginBean extends AbstractExtensionPointBean { + public static final ExtensionPointName<JpsPluginBean> EP_NAME = ExtensionPointName.create("com.intellij.jps.plugin"); } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 308d5dbb1835..7c8acbc4c25c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -767,12 +767,12 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App @Override public void exit() { - exit(false); + exit(false, false); } @Override - public void exit(final boolean force) { - exit(force, true, false); + public void exit(boolean force, final boolean exitConfirmed) { + exit(false, exitConfirmed, true, false); } @Override @@ -781,8 +781,8 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App } @Override - public void restart(boolean force) { - exit(force, true, true); + public void restart(boolean exitConfirmed) { + exit(false, exitConfirmed, true, true); } /* @@ -796,7 +796,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App */ private static volatile boolean exiting = false; - public void exit(final boolean force, final boolean allowListenersToCancel, final boolean restart) { + public void exit(final boolean force, final boolean exitConfirmed, final boolean allowListenersToCancel, final boolean restart) { if (exiting) return; exiting = true; @@ -808,7 +808,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App Runnable runnable = new Runnable() { @Override public void run() { - if (!confirmExitIfNeeded(force)) { + if (!force && !confirmExitIfNeeded(exitConfirmed)) { saveAll(); return; } @@ -857,9 +857,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App return true; } - private static boolean confirmExitIfNeeded(boolean force) { + private static boolean confirmExitIfNeeded(boolean exitConfirmed) { final boolean hasUnsafeBgTasks = ProgressManager.getInstance().hasUnsafeProgressIndicator(); - if (force && !hasUnsafeBgTasks) { + if (exitConfirmed && !hasUnsafeBgTasks) { return true; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/Rediffers.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/Rediffers.java index a29e51930119..3a1f8b055ab5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/Rediffers.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/Rediffers.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +24,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Alarm; import com.intellij.util.containers.HashMap; -import java.util.Iterator; - public class Rediffers { private final HashMap<EditorSource, Rediff> myRediffers = new HashMap<EditorSource, Rediff>(); private final DiffPanelImpl myPanel; @@ -43,8 +41,7 @@ public class Rediffers { } public void dispose() { - for (Iterator<Rediff> iterator = myRediffers.values().iterator(); iterator.hasNext();) { - Rediff rediff = iterator.next(); + for (Rediff rediff : myRediffers.values()) { rediff.stopListen(); } myRediffers.clear(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java index 8b7791086014..a0355cf71222 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java @@ -601,7 +601,9 @@ public class EditorActionUtil { } } caretModel.moveToOffset(newOffset); - editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + if (editor.getCaretModel().getCurrentCaret() == editor.getCaretModel().getPrimaryCaret()) { + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); } @@ -673,7 +675,9 @@ public class EditorActionUtil { if (isWordStart(text, newOffset, camel)) break; } editor.getCaretModel().moveToOffset(newOffset); - editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + if (editor.getCaretModel().getCurrentCaret() == editor.getCaretModel().getPrimaryCaret()) { + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java index 48d43bcce8bd..e3c03c2fbbd4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.openapi.editor.ex; import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; import com.intellij.openapi.editor.impl.softwrap.SoftWrapDrawingType; import org.jetbrains.annotations.NotNull; @@ -149,4 +150,6 @@ public interface SoftWrapModelEx extends SoftWrapModel { * Allows to instruct current model to always return <code>'true'</code> from {@link #isRespectAdditionalColumns()}. */ void forceAdditionalColumnsUsage(); + + EditorTextRepresentationHelper getEditorTextRepresentationHelper(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/BorderEffect.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/BorderEffect.java index cc1a23f6f8e5..2872699c8012 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/BorderEffect.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/BorderEffect.java @@ -86,6 +86,8 @@ public class BorderEffect { markupModel.processRangeHighlightersOverlappingWith(myStartOffset, myEndOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx rangeHighlighter) { + if (!rangeHighlighter.getEditorFilter().avaliableIn(myEditor)) return true; + TextAttributes textAttributes = rangeHighlighter.getTextAttributes(); if (isBorder(textAttributes) && intersectsRange(rangeHighlighter)) { paintBorder(rangeHighlighter, textAttributes); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java index 068f25e16565..cfd039a5d504 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java @@ -1453,10 +1453,17 @@ public class CaretImpl extends UserDataHolderBase implements Caret { return marker != null && marker.isValid() && isVirtualSelectionEnabled() && myEndVirtualOffset > myStartVirtualOffset; } + @Override + @NotNull public EditorImpl getEditor() { return myEditor; } + @Override + public String toString() { + return "Caret at " + myVisibleCaret + (mySelectionMarker == null ? "" : (", selection marker: " + mySelectionMarker.toString())); + } + /** * Encapsulates information about target vertical range info - its <code>'y'</code> coordinate and height in pixels. */ diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java index a18d45472454..8d6608e63dd9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java @@ -282,11 +282,9 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, } } - boolean addCaret(CaretImpl caretToAdd) { + boolean addCaret(@NotNull CaretImpl caretToAdd) { for (CaretImpl caret : myCarets) { - VisualPosition newVisualPosition = caretToAdd.getVisualPosition(); - int newOffset = myEditor.logicalPositionToOffset(myEditor.visualToLogicalPosition(newVisualPosition)); - if (caret.getVisualPosition().equals(newVisualPosition) || newOffset >= caret.getSelectionStart() && newOffset <= caret.getSelectionEnd()) { + if (caretsOverlap(caret, caretToAdd)) { return false; } } @@ -384,8 +382,7 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, it.next(); } CaretImpl currCaret = it.next(); - if (prevCaret != null && (currCaret.getVisualPosition().equals(prevCaret.getVisualPosition()) - || selectionsIntersect(currCaret, prevCaret))) { + if (prevCaret != null && caretsOverlap(currCaret, prevCaret)) { int newSelectionStart = Math.min(currCaret.getSelectionStart(), prevCaret.getSelectionStart()); int newSelectionEnd = Math.max(currCaret.getSelectionEnd(), prevCaret.getSelectionEnd()); CaretImpl toRetain, toRemove; @@ -410,7 +407,10 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, } } - private static boolean selectionsIntersect(CaretImpl firstCaret, CaretImpl secondCaret) { + private static boolean caretsOverlap(@NotNull CaretImpl firstCaret, @NotNull CaretImpl secondCaret) { + if (firstCaret.getVisualPosition().equals(secondCaret.getVisualPosition())) { + return true; + } int firstStart = firstCaret.getSelectionStart(); int secondStart = secondCaret.getSelectionStart(); int firstEnd = firstCaret.getSelectionEnd(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java index 9b2e473a0da5..61415eb90ce4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,14 @@ package com.intellij.openapi.editor.impl; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.ex.util.EditorUtil; import gnu.trove.TObjectIntHashMap; import org.intellij.lang.annotations.JdkConstants; import org.jetbrains.annotations.NotNull; /** - * Not thread-safe. + * Not thread-safe. Performs caching of char widths, so cache reset must be invoked (via {@link #clearSymbolWidthCache()} method) when + * font settings are changed in editor. * * @author Denis Zhdanov * @since Jul 27, 2010 4:06:27 PM @@ -60,9 +60,6 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen public int charWidth(char c, int fontType) { // Symbol width retrieval is detected to be a bottleneck, hence, we perform a caching here in assumption that every representation // helper is editor-bound and cache size is not too big. - EditorColorsScheme colorsScheme = myEditor.getColorsScheme(); - mySharedKey.fontName = colorsScheme.getEditorFontName(); - mySharedKey.fontSize = colorsScheme.getEditorFontSize(); mySharedKey.fontType = fontType; mySharedKey.c = c; @@ -83,9 +80,6 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen // Symbol width retrieval is detected to be a bottleneck, hence, we perform a caching here in assumption that every representation // helper is editor-bound and cache size is not too big. - EditorColorsScheme colorsScheme = myEditor.getColorsScheme(); - mySharedKey.fontName = colorsScheme.getEditorFontName(); - mySharedKey.fontSize = colorsScheme.getEditorFontSize(); mySharedKey.fontType = fontType; for (int i = startToUse; i < end; i++) { @@ -107,7 +101,7 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen return result; } Key key = mySharedKey.clone(); - FontInfo font = ComplementaryFontsRegistry.getFontAbleToDisplay(c, key.fontSize, key.fontType, key.fontName); + FontInfo font = ComplementaryFontsRegistry.getFontAbleToDisplay(c, key.fontType, myEditor.getColorsScheme().getFontPreferences()); result = font.charWidth(c); if (mySymbolWidthCache.size() >= MAX_SYMBOLS_WIDTHS_CACHE_SIZE) { // Don't expect to be here. @@ -117,33 +111,31 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen return result; } + public void clearSymbolWidthCache() { + mySymbolWidthCache.clear(); + } + private static class Key { - public String fontName; - private int fontSize; @JdkConstants.FontStyle private int fontType; private char c; private Key() { - this(null, 0, 0, ' '); + this(0, ' '); } - Key(String fontName, int fontSize, @JdkConstants.FontStyle int fontType, char c) { - this.fontName = fontName; - this.fontSize = fontSize; + Key(@JdkConstants.FontStyle int fontType, char c) { this.fontType = fontType; this.c = c; } @Override protected Key clone() { - return new Key(fontName, fontSize, fontType, c); + return new Key(fontType, c); } @Override public int hashCode() { - int result = fontName != null ? fontName.hashCode() : 0; - result = 31 * result + fontSize; - result = 31 * result + fontType; + int result = fontType; result = 31 * result + c; return result; } @@ -155,10 +147,8 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen Key key = (Key)o; - if (fontSize != key.fontSize) return false; if (fontType != key.fontType) return false; if (c != key.c) return false; - if (fontName != null ? !fontName.equals(key.fontName) : key.fontName != null) return false; return true; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index e37ad8f968ad..b708f38a9190 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -66,6 +66,8 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.IdeGlassPane; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.ui.*; @@ -320,7 +322,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myScheme = createBoundColorSchemeDelegate(null); initTabPainter(); myIsViewer = viewer; - mySettings = new SettingsImpl(this); + mySettings = new SettingsImpl(this, project); mySelectionModel = new SelectionModelImpl(this); myMarkupModel = new EditorMarkupModelImpl(this); @@ -1979,6 +1981,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myMarkupModel.processRangeHighlightersOverlappingWith(clipStartOffset, clipEndOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(@NotNull RangeHighlighterEx highlighter) { + if (!highlighter.getEditorFilter().avaliableIn(EditorImpl.this)) return true; + final CustomHighlighterRenderer customRenderer = highlighter.getCustomRenderer(); if (customRenderer != null && clipStartOffset < highlighter.getEndOffset() && highlighter.getStartOffset() < clipEndOffset) { customRenderer.paint(EditorImpl.this, highlighter, g); @@ -2124,6 +2128,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi Processor<RangeHighlighterEx> paintProcessor = new Processor<RangeHighlighterEx>() { @Override public boolean process(@NotNull RangeHighlighterEx highlighter) { + if (!highlighter.getEditorFilter().avaliableIn(EditorImpl.this)) return true; + paintSegmentHighlighterAfterEndOfLine(g, highlighter, startLine, endLine); return true; } @@ -2978,6 +2984,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi markupModel.processRangeHighlightersOverlappingWith(clipStartOffset, clipEndOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(@NotNull RangeHighlighterEx lineMarker) { + if (!lineMarker.getEditorFilter().avaliableIn(EditorImpl.this)) return true; + paintLineMarkerSeparator(lineMarker, clip, g); return true; } @@ -6735,7 +6743,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } } - private static class TablessBorder extends SideBorder { + private class TablessBorder extends SideBorder { private TablessBorder() { super(UIUtil.getBorderColor(), SideBorder.ALL); } @@ -6760,7 +6768,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi @Override public Insets getBorderInsets(Component c) { Container splitters = SwingUtilities.getAncestorOfClass(EditorsSplitters.class, c); - return splitters == null ? super.getBorderInsets(c) : new Insets(1, 0, 0, 0); + boolean thereIsSomethingAbove = !SystemInfo.isMac || UISettings.getInstance().SHOW_MAIN_TOOLBAR || UISettings.getInstance().SHOW_NAVIGATION_BAR || + EditorImpl.this.myProject != null && !ToolWindowManagerEx.getInstanceEx(EditorImpl.this.myProject).getIdsOn(ToolWindowAnchor.TOP).isEmpty(); + return splitters == null ? super.getBorderInsets(c) : new Insets(thereIsSomethingAbove ? 1 : 0, 0, 0, 0); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java index c721a5a5873b..a2f45fe33857 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java @@ -45,6 +45,7 @@ import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.ProperTextRange; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.wm.ToolWindowAnchor; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; import com.intellij.ui.*; @@ -229,6 +230,8 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark markupModel.processRangeHighlightersOverlappingWith(startOffset, endOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx highlighter) { + if (!highlighter.getEditorFilter().avaliableIn(myEditor)) return true; + if (highlighter.getErrorStripeMarkColor() != null) { if (highlighter.getStartOffset() < endOffset && highlighter.getEndOffset() > startOffset) { highlighters.add(highlighter); @@ -266,6 +269,8 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark markupModel.processRangeHighlightersOverlappingWith(startOffset, endOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx highlighter) { + if (!highlighter.getEditorFilter().avaliableIn(myEditor)) return true; + if (highlighter.getErrorStripeMarkColor() != null) { ProperTextRange range = offsetsToYPositions(highlighter.getStartOffset(), highlighter.getEndOffset()); if (scrollBarY >= range.getStartOffset() - myMinMarkHeight * 2 && @@ -432,7 +437,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark errorIconBounds.y = bounds.height / 2 - errorIconBounds.height / 2; try { - if (UISettings.getInstance().PRESENTATION_MODE) { + if (UISettings.getInstance().PRESENTATION_MODE || SystemInfo.isMac) { g.setColor(getEditor().getColorsScheme().getDefaultBackground()); g.fillRect(0, 0, bounds.width, bounds.height); @@ -523,7 +528,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark @Override protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) { - if (UISettings.getInstance().PRESENTATION_MODE) { + if (UISettings.getInstance().PRESENTATION_MODE || SystemInfo.isMac) { super.paintThumb(g, c, thumbBounds); return; } @@ -560,16 +565,16 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark @Override protected int getThickness() { - if (UISettings.getInstance().PRESENTATION_MODE) return super.getThickness(); + if (UISettings.getInstance().PRESENTATION_MODE || SystemInfo.isMac) return super.getThickness(); return super.getThickness() + (isMacOverlayScrollbar() ? 2 : 7); } @Override protected void doPaintTrack(Graphics g, JComponent c, Rectangle bounds) { - if (UISettings.getInstance().PRESENTATION_MODE) { + if (UISettings.getInstance().PRESENTATION_MODE || SystemInfo.isMac) { g.setColor(getEditor().getColorsScheme().getDefaultBackground()); g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); - return; + //return; } Rectangle clip = g.getClipBounds().intersection(bounds); if (clip.height == 0) return; @@ -604,7 +609,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark } private void paintTrackBasement(Graphics g, Rectangle bounds) { - if (UISettings.getInstance().PRESENTATION_MODE) { + if (UISettings.getInstance().PRESENTATION_MODE || SystemInfo.isMac) { return; } @@ -661,6 +666,8 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark markup.processRangeHighlightersOverlappingWith(startOffset, endOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx highlighter) { + if (!highlighter.getEditorFilter().avaliableIn(myEditor)) return true; + Color color = highlighter.getErrorStripeMarkColor(); if (color == null) return true; boolean isThin = highlighter.isThinErrorStripeMark(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java index 694bc75a5751..b92970425e99 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java @@ -265,9 +265,6 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList if (line >= myEditor.getDocument().getLineCount()) return null; - //leftmost folded block position - if (myEditor.xyToVisualPosition(p).equals(myEditor.logicalToVisualPosition(pos))) return null; - int offset = myEditor.logicalPositionToOffset(pos); return myFoldTree.fetchOutermost(offset); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java index 263ea77c286f..2f5a81153579 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java @@ -36,16 +36,13 @@ import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.editor.ex.PrioritizedDocumentListener; import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.editor.markup.TextAttributes; -import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; import gnu.trove.TIntArrayList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.awt.datatransfer.StringSelection; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; @@ -570,13 +567,7 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi @Override public void copySelectionToClipboard() { - validateContext(true); - String s = getSelectedText(true); - if (s == null) return; - - s = StringUtil.convertLineSeparators(s); - StringSelection contents = new StringSelection(s); - CopyPasteManager.getInstance().setContents(contents); + CopyPasteSupport.copySelectionToClipboard(myEditor); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java index dabf5e9d2a2f..f2dbc6756ef5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SettingsImpl.java @@ -25,6 +25,8 @@ package com.intellij.openapi.editor.impl; import com.intellij.codeStyle.CodeStyleFacade; +import com.intellij.lang.Language; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.EditorSettings; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; @@ -32,10 +34,14 @@ import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class SettingsImpl implements EditorSettings { @Nullable private final EditorEx myEditor; + @Nullable private final Language myLanguage; private Boolean myIsCamelWords; // This group of settings does not have UI @@ -78,9 +84,14 @@ public class SettingsImpl implements EditorSettings { private Boolean myRenamePreselect = null; private Boolean myWrapWhenTypingReachesRightMargin = null; private Boolean myShowIntentionBulb = null; + + public SettingsImpl() { + this(null, null); + } - public SettingsImpl(@Nullable EditorEx editor) { + public SettingsImpl(@Nullable EditorEx editor, @Nullable Project project) { myEditor = editor; + myLanguage = editor != null && project != null ? getDocumentLanguage(project, editor.getDocument()) : null; } @Override @@ -144,7 +155,17 @@ public class SettingsImpl implements EditorSettings { @Override public int getRightMargin(Project project) { return myRightMargin != null ? myRightMargin.intValue() : - CodeStyleFacade.getInstance(project).getRightMargin(); + CodeStyleFacade.getInstance(project).getRightMargin(myLanguage); + } + + @Nullable + private static Language getDocumentLanguage(@Nullable Project project, @NotNull Document document) { + if (project != null) { + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); + PsiFile file = documentManager.getPsiFile(document); + if (file != null) return file.getLanguage(); + } + return null; } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java index cccf86c5f98e..6f1b9820132b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java @@ -21,6 +21,7 @@ import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.colors.FontPreferences; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.event.DocumentListener; import com.intellij.openapi.editor.ex.*; @@ -89,9 +90,10 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi private SoftWrapPainter myPainter; private final SoftWrapApplianceManager myApplianceManager; private final SoftWrapAwareVisualSizeManager myVisualSizeManager; + private EditorTextRepresentationHelper myEditorTextRepresentationHelper; private final EditorEx myEditor; - + /** * We don't want to use soft wraps-aware processing from non-EDT and profiling shows that 'is EDT' check that is called too * often is rather expensive. Hence, we use caching here for performance improvement. @@ -101,6 +103,8 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi private int myActive; private boolean myUseSoftWraps; private int myTabWidth = -1; + @NotNull + private FontPreferences myFontPreferences; /** * Soft wraps need to be kept up-to-date on all editor modification (changing text, adding/removing/expanding/collapsing fold @@ -132,9 +136,9 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi myEditor = editor; myStorage = new SoftWrapsStorage(); myPainter = new CompositeSoftWrapPainter(editor); - DefaultEditorTextRepresentationHelper representationHelper = new DefaultEditorTextRepresentationHelper(editor); - myDataMapper = new CachingSoftWrapDataMapper(editor, myStorage, representationHelper); - myApplianceManager = new SoftWrapApplianceManager(myStorage, editor, myPainter, representationHelper, myDataMapper); + myEditorTextRepresentationHelper = new DefaultEditorTextRepresentationHelper(editor); + myDataMapper = new CachingSoftWrapDataMapper(editor, myStorage); + myApplianceManager = new SoftWrapApplianceManager(myStorage, editor, myPainter, myDataMapper); myFoldBasedApplianceStrategy = new SoftWrapFoldBasedApplianceStrategy(editor); myVisualSizeManager = new SoftWrapAwareVisualSizeManager(myPainter); @@ -150,6 +154,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi }); EditorSettings settings = myEditor.getSettings(); myUseSoftWraps = settings.isUseSoftWraps(); + myFontPreferences = myEditor.getColorsScheme().getFontPreferences(); editor.addPropertyChangeListener(this); @@ -168,8 +173,16 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi int tabWidthBefore = myTabWidth; myTabWidth = getCurrentTabWidth(); + + boolean fontsChanged = false; + if (!myFontPreferences.equals(myEditor.getColorsScheme().getFontPreferences()) + && myEditorTextRepresentationHelper instanceof DefaultEditorTextRepresentationHelper) { + fontsChanged = true; + myFontPreferences = myEditor.getColorsScheme().getFontPreferences(); + ((DefaultEditorTextRepresentationHelper)myEditorTextRepresentationHelper).clearSymbolWidthCache(); + } - if ((myUseSoftWraps ^ softWrapsUsedBefore) || (tabWidthBefore >= 0 && myTabWidth != tabWidthBefore)) { + if ((myUseSoftWraps ^ softWrapsUsedBefore) || (tabWidthBefore >= 0 && myTabWidth != tabWidthBefore) || fontsChanged) { myApplianceManager.reset(); myDeferredFoldRegions.clear(); myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); @@ -705,6 +718,20 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi myVisualSizeManager.setSoftWrapPainter(painter); } + public static EditorTextRepresentationHelper getEditorTextRepresentationHelper(@NotNull Editor editor) { + return ((SoftWrapModelEx)editor.getSoftWrapModel()).getEditorTextRepresentationHelper(); + } + + public EditorTextRepresentationHelper getEditorTextRepresentationHelper() { + return myEditorTextRepresentationHelper; + } + + @TestOnly + public void setEditorTextRepresentationHelper(EditorTextRepresentationHelper editorTextRepresentationHelper) { + myEditorTextRepresentationHelper = editorTextRepresentationHelper; + myApplianceManager.reset(); + } + @NotNull @Override public String dumpState() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/AbstractMappingStrategy.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/AbstractMappingStrategy.java index 26c8086beb72..bccdf4c59336 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/AbstractMappingStrategy.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/AbstractMappingStrategy.java @@ -15,12 +15,10 @@ */ package com.intellij.openapi.editor.impl.softwrap.mapping; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.FoldRegion; import com.intellij.openapi.editor.LogicalPosition; -import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,10 +37,7 @@ import java.util.List; */ abstract class AbstractMappingStrategy<T> implements MappingStrategy<T> { - private static final Logger LOG = Logger.getInstance("#" + AbstractMappingStrategy.class.getName()); - protected final Editor myEditor; - protected final EditorTextRepresentationHelper myRepresentationHelper; protected final SoftWrapsStorage myStorage; protected final List<CacheEntry> myCache; @@ -53,13 +48,11 @@ abstract class AbstractMappingStrategy<T> implements MappingStrategy<T> { AbstractMappingStrategy(@NotNull Editor editor, @NotNull SoftWrapsStorage storage, - @NotNull List<CacheEntry> cache, - @NotNull EditorTextRepresentationHelper representationHelper) + @NotNull List<CacheEntry> cache) { myEditor = editor; myStorage = storage; myCache = cache; - myRepresentationHelper = representationHelper; } @Nullable @@ -73,7 +66,7 @@ abstract class AbstractMappingStrategy<T> implements MappingStrategy<T> { } protected void setFirstInitialPosition() { - myInitialPosition = new EditorPosition(new LogicalPosition(0, 0), 0, myEditor, myRepresentationHelper); + myInitialPosition = new EditorPosition(new LogicalPosition(0, 0), 0, myEditor); } @Nullable diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CacheEntry.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CacheEntry.java index 57ef56c178e9..27362b52527a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CacheEntry.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CacheEntry.java @@ -17,7 +17,6 @@ package com.intellij.openapi.editor.impl.softwrap.mapping; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.FoldRegion; -import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; import com.intellij.openapi.util.Ref; import gnu.trove.TIntObjectHashMap; import gnu.trove.TIntObjectProcedure; @@ -25,7 +24,10 @@ import gnu.trove.TObjectProcedure; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Encapsulates information to cache for the single visual line. @@ -59,7 +61,6 @@ class CacheEntry implements Comparable<CacheEntry>, Cloneable { public boolean locked; private final Editor myEditor; - private final EditorTextRepresentationHelper myRepresentationHelper; /** Holds positions for the tabulation symbols on a target visual line sorted by offset in ascending order. */ private List<TabData> myTabPositions = Collections.EMPTY_LIST; @@ -67,10 +68,9 @@ class CacheEntry implements Comparable<CacheEntry>, Cloneable { /** Holds information about single line fold regions representation data. */ private TIntObjectHashMap<FoldingData> myFoldingData = DUMMY; - CacheEntry(int visualLine, @NotNull Editor editor, @NotNull EditorTextRepresentationHelper representationHelper) { + CacheEntry(int visualLine, @NotNull Editor editor) { this.visualLine = visualLine; myEditor = editor; - myRepresentationHelper = representationHelper; } public void setLineStartPosition(@NotNull EditorPosition context) { @@ -99,7 +99,7 @@ class CacheEntry implements Comparable<CacheEntry>, Cloneable { } public EditorPosition buildStartLinePosition() { - EditorPosition result = new EditorPosition(myEditor, myRepresentationHelper); + EditorPosition result = new EditorPosition(myEditor); result.logicalLine = startLogicalLine; result.logicalColumn = startLogicalColumn; result.offset = startOffset; @@ -114,7 +114,7 @@ class CacheEntry implements Comparable<CacheEntry>, Cloneable { } public EditorPosition buildEndLinePosition() { - EditorPosition result = new EditorPosition(myEditor, myRepresentationHelper); + EditorPosition result = new EditorPosition(myEditor); result.logicalLine = endLogicalLine; result.logicalColumn = endLogicalColumn; result.offset = endOffset; @@ -246,7 +246,7 @@ class CacheEntry implements Comparable<CacheEntry>, Cloneable { @Override protected CacheEntry clone() { - final CacheEntry result = new CacheEntry(visualLine, myEditor, myRepresentationHelper); + final CacheEntry result = new CacheEntry(visualLine, myEditor); result.startLogicalLine = startLogicalLine; result.startLogicalColumn = startLogicalColumn; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java index 08bf0211dbc8..2f21b0319af2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java @@ -21,7 +21,7 @@ import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.FoldingModelEx; import com.intellij.openapi.editor.impl.EditorImpl; -import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; +import com.intellij.openapi.editor.impl.SoftWrapModelImpl; import com.intellij.openapi.editor.impl.softwrap.SoftWrapDataMapper; import com.intellij.openapi.editor.impl.softwrap.SoftWrapImpl; import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage; @@ -71,19 +71,16 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw private final VisualToLogicalCalculationStrategy myVisualToLogicalStrategy; private final EditorEx myEditor; private final SoftWrapsStorage myStorage; - private final EditorTextRepresentationHelper myRepresentationHelper; private final CacheEntry mySearchKey; - public CachingSoftWrapDataMapper(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, - @NotNull EditorTextRepresentationHelper representationHelper) + public CachingSoftWrapDataMapper(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage) { myEditor = editor; myStorage = storage; - myRepresentationHelper = representationHelper; - mySearchKey = new CacheEntry(0, editor, representationHelper); + mySearchKey = new CacheEntry(0, editor); - myOffsetToLogicalStrategy = new OffsetToLogicalCalculationStrategy(editor, storage, myCache, representationHelper); - myVisualToLogicalStrategy = new VisualToLogicalCalculationStrategy(editor, storage, myCache, representationHelper); + myOffsetToLogicalStrategy = new OffsetToLogicalCalculationStrategy(editor, storage, myCache); + myVisualToLogicalStrategy = new VisualToLogicalCalculationStrategy(editor, storage, myCache); } @NotNull @@ -146,7 +143,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw // Count soft wrap column offset only if it's located at the same line as the target offset. if (column < 0 && softWrap.getStart() >= targetLogicalLineStartOffset) { - column = softWrap.getIndentInColumns() + myRepresentationHelper.toVisualColumnSymbolsNumber( + column = softWrap.getIndentInColumns() + SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor).toVisualColumnSymbolsNumber( myEditor.getDocument().getCharsSequence(), softWrap.getStart(), maxOffset, softWrap.getIndentInPixels() ); @@ -326,7 +323,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw return lastEntry; } else if (lastEntry.visualLine < visualLine && createIfNecessary) { - CacheEntry result = new CacheEntry(visualLine, myEditor, myRepresentationHelper); + CacheEntry result = new CacheEntry(visualLine, myEditor); myCache.add(result); return result; } @@ -357,7 +354,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw if (cacheEntryIndex < 0) { cacheEntryIndex = start; if (createIfNecessary) { - myCache.add(cacheEntryIndex, result = new CacheEntry(visualLine, myEditor, myRepresentationHelper)); + myCache.add(cacheEntryIndex, result = new CacheEntry(visualLine, myEditor)); } } else { @@ -666,7 +663,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw @NotNull List<Pair<Integer, FoldRegion>> foldRegions, @NotNull List<Pair<Integer, Integer>> tabData) { - final CacheEntry entry = new CacheEntry(visualLine, myEditor, myRepresentationHelper); + final CacheEntry entry = new CacheEntry(visualLine, myEditor); entry.startOffset = startOffset; entry.endOffset = endOffset; entry.startLogicalLine = startLogicalLine; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/EditorPosition.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/EditorPosition.java index 903243cfa766..1097f2824445 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/EditorPosition.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/EditorPosition.java @@ -16,7 +16,7 @@ package com.intellij.openapi.editor.impl.softwrap.mapping; import com.intellij.openapi.editor.*; -import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; +import com.intellij.openapi.editor.impl.SoftWrapModelImpl; import org.jetbrains.annotations.NotNull; /** @@ -46,29 +46,24 @@ class EditorPosition implements Cloneable { public int symbolWidthInPixels; private final Editor myEditor; - private final EditorTextRepresentationHelper myRepresentationHelper; - EditorPosition(@NotNull Editor editor, @NotNull EditorTextRepresentationHelper representationHelper) { + EditorPosition(@NotNull Editor editor) { myEditor = editor; - myRepresentationHelper = representationHelper; } EditorPosition(@NotNull LogicalPosition logical, int offset, - @NotNull Editor editor, - @NotNull EditorTextRepresentationHelper representationHelper) + @NotNull Editor editor) { - this(logical, logical.toVisualPosition(), offset, editor, representationHelper); + this(logical, logical.toVisualPosition(), offset, editor); } EditorPosition(@NotNull LogicalPosition logical, @NotNull VisualPosition visual, int offset, - @NotNull Editor editor, - @NotNull EditorTextRepresentationHelper representationHelper) + @NotNull Editor editor) { myEditor = editor; - myRepresentationHelper = representationHelper; logicalLine = logical.line; logicalColumn = logical.column; softWrapLinesBefore = logical.softWrapLinesBeforeCurrentLogicalLine; @@ -148,10 +143,11 @@ class EditorPosition implements Cloneable { if (logicalLine == endOffsetLogicalLine) { // Single-line fold region. if (collapsedSymbolsWidthInColumns < 0) { - collapsedSymbolsWidthInColumns = myRepresentationHelper.toVisualColumnSymbolsNumber(document.getCharsSequence(), - foldRegion.getStartOffset(), - foldRegion.getEndOffset(), - x); + collapsedSymbolsWidthInColumns = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor) + .toVisualColumnSymbolsNumber(document.getCharsSequence(), + foldRegion.getStartOffset(), + foldRegion.getEndOffset(), + x); } logicalColumn += collapsedSymbolsWidthInColumns; foldingColumnDiff += placeholder.length() - collapsedSymbolsWidthInColumns; @@ -159,10 +155,11 @@ class EditorPosition implements Cloneable { else { // Multi-line fold region. if (collapsedSymbolsWidthInColumns < 0) { - collapsedSymbolsWidthInColumns = myRepresentationHelper.toVisualColumnSymbolsNumber(document.getCharsSequence(), - foldRegion.getStartOffset(), - foldRegion.getEndOffset(), - 0); + collapsedSymbolsWidthInColumns = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor) + .toVisualColumnSymbolsNumber(document.getCharsSequence(), + foldRegion.getStartOffset(), + foldRegion.getEndOffset(), + 0); } int linesDiff = endOffsetLogicalLine - logicalLine; logicalLine += linesDiff; @@ -191,7 +188,7 @@ class EditorPosition implements Cloneable { @Override protected EditorPosition clone() { - EditorPosition result = new EditorPosition(myEditor, myRepresentationHelper); + EditorPosition result = new EditorPosition(myEditor); result.logicalLine = logicalLine; result.logicalColumn = logicalColumn; result.visualLine = visualLine; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToVisualMappingStrategy.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToVisualMappingStrategy.java index 773d4fdc4d82..6ed904624fa6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToVisualMappingStrategy.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToVisualMappingStrategy.java @@ -16,7 +16,7 @@ package com.intellij.openapi.editor.impl.softwrap.mapping; import com.intellij.openapi.editor.*; -import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; +import com.intellij.openapi.editor.impl.SoftWrapModelImpl; import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage; import org.jetbrains.annotations.NotNull; @@ -32,10 +32,10 @@ class LogicalToVisualMappingStrategy extends AbstractMappingStrategy<VisualPosit private LogicalPosition myTargetLogical; LogicalToVisualMappingStrategy(@NotNull LogicalPosition logical, @NotNull Editor editor, @NotNull SoftWrapsStorage storage, - @NotNull EditorTextRepresentationHelper representationHelper, @NotNull List<CacheEntry> cache) + @NotNull List<CacheEntry> cache) throws IllegalStateException { - super(editor, storage, cache, representationHelper); + super(editor, storage, cache); myTargetLogical = logical; } @@ -121,7 +121,7 @@ class LogicalToVisualMappingStrategy extends AbstractMappingStrategy<VisualPosit int foldEndColumn; if (data == null) { int xStart = myEditor.getDocument().getLineNumber(foldRegion.getStartOffset()) == foldEndLine ? context.x : 0; - foldEndColumn = myRepresentationHelper.toVisualColumnSymbolsNumber( + foldEndColumn = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor).toVisualColumnSymbolsNumber( myEditor.getDocument().getCharsSequence(), foldRegion.getStartOffset(), foldRegion.getEndOffset(), xStart ); } else { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/OffsetToLogicalCalculationStrategy.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/OffsetToLogicalCalculationStrategy.java index 39fe252ec623..399406f2db32 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/OffsetToLogicalCalculationStrategy.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/OffsetToLogicalCalculationStrategy.java @@ -16,7 +16,7 @@ package com.intellij.openapi.editor.impl.softwrap.mapping; import com.intellij.openapi.editor.*; -import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; +import com.intellij.openapi.editor.impl.SoftWrapModelImpl; import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,10 +31,9 @@ class OffsetToLogicalCalculationStrategy extends AbstractMappingStrategy<Logical private int myTargetOffset; - OffsetToLogicalCalculationStrategy(@NotNull Editor editor, @NotNull SoftWrapsStorage storage, @NotNull List<CacheEntry> cache, - @NotNull EditorTextRepresentationHelper representationHelper) + OffsetToLogicalCalculationStrategy(@NotNull Editor editor, @NotNull SoftWrapsStorage storage, @NotNull List<CacheEntry> cache) { - super(editor, storage, cache, representationHelper); + super(editor, storage, cache); } public void init(final int targetOffset, final List<CacheEntry> cache) { @@ -157,13 +156,13 @@ class OffsetToLogicalCalculationStrategy extends AbstractMappingStrategy<Logical int targetLogicalLine = document.getLineNumber(myTargetOffset); if (targetLogicalLine == position.logicalLine) { // Target offset is located on the same logical line as folding start. - position.logicalColumn += myRepresentationHelper.toVisualColumnSymbolsNumber( + position.logicalColumn += SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor).toVisualColumnSymbolsNumber( document.getCharsSequence(), foldRegion.getStartOffset(), myTargetOffset, position.x ); } else { // Target offset is located on a different line with folding start. - position.logicalColumn = myRepresentationHelper.toVisualColumnSymbolsNumber( + position.logicalColumn = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor).toVisualColumnSymbolsNumber( document.getCharsSequence(), foldRegion.getStartOffset(), myTargetOffset, 0 ); position.softWrapColumnDiff = 0; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java index 549cd1833779..3a819d88a370 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java @@ -28,10 +28,7 @@ import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.ScrollingModelEx; import com.intellij.openapi.editor.ex.util.EditorUtil; -import com.intellij.openapi.editor.impl.EditorImpl; -import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; -import com.intellij.openapi.editor.impl.IterationState; -import com.intellij.openapi.editor.impl.TextChangeImpl; +import com.intellij.openapi.editor.impl.*; import com.intellij.openapi.editor.impl.softwrap.*; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.util.text.StringUtil; @@ -99,7 +96,6 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable { private int myVerticalScrollBarWidth = -1; private VisibleAreaWidthProvider myWidthProvider; - private EditorTextRepresentationHelper myRepresentationHelper; private LineWrapPositionStrategy myLineWrapPositionStrategy; private IncrementalCacheUpdateEvent myEventBeingProcessed; private boolean myVisualAreaListenerAttached; @@ -112,12 +108,11 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable { public SoftWrapApplianceManager(@NotNull SoftWrapsStorage storage, @NotNull EditorEx editor, @NotNull SoftWrapPainter painter, - @NotNull EditorTextRepresentationHelper representationHelper, SoftWrapDataMapper dataMapper) + SoftWrapDataMapper dataMapper) { myStorage = storage; myEditor = editor; myPainter = painter; - myRepresentationHelper = representationHelper; myDataMapper = dataMapper; myWidthProvider = new DefaultVisibleAreaWidthProvider(editor); } @@ -272,7 +267,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable { myContext.fontType = attributes.getFontType(); myContext.rangeEndOffset = event.getNewEndOffset(); - EditorPosition position = new EditorPosition(logical, start, myEditor, myRepresentationHelper); + EditorPosition position = new EditorPosition(logical, start, myEditor); position.x = point.x; int spaceWidth = EditorUtil.getSpaceWidth(myContext.fontType, myEditor); @@ -333,7 +328,8 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable { } int placeholderWidthInPixels = 0; for (int i = 0; i < placeholder.length(); i++) { - placeholderWidthInPixels += myRepresentationHelper.charWidth(placeholder.charAt(i), myContext.fontType); + placeholderWidthInPixels += SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor) + .charWidth(placeholder.charAt(i), myContext.fontType); } int newX = myContext.currentPosition.x + placeholderWidthInPixels; @@ -617,7 +613,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable { return EditorUtil.nextTabStop(myContext.currentPosition.x, myEditor); } else { - return myContext.currentPosition.x + myRepresentationHelper.charWidth(c, myContext.fontType); + return myContext.currentPosition.x + SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor).charWidth(c, myContext.fontType); //FontInfo fontInfo = EditorUtil.fontForChar(c, myContext.fontType, myEditor); //return myContext.currentPosition.x + fontInfo.charWidth(c, myContext.contentComponent); } @@ -1009,11 +1005,6 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable { reset(); } - public void setRepresentationHelper(@NotNull EditorTextRepresentationHelper representationHelper) { - myRepresentationHelper = representationHelper; - reset(); - } - @NotNull @Override public String dumpState() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/VisualToLogicalCalculationStrategy.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/VisualToLogicalCalculationStrategy.java index d79e3bff8f63..7c7c6e475a4f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/VisualToLogicalCalculationStrategy.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/VisualToLogicalCalculationStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.intellij.openapi.editor.impl.softwrap.mapping; import com.intellij.openapi.editor.*; -import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,11 +32,10 @@ class VisualToLogicalCalculationStrategy extends AbstractMappingStrategy<Logical private final CacheEntry mySearchKey; private VisualPosition myTargetVisual; - VisualToLogicalCalculationStrategy(@NotNull Editor editor, @NotNull SoftWrapsStorage storage, @NotNull List<CacheEntry> cache, - @NotNull EditorTextRepresentationHelper representationHelper) + VisualToLogicalCalculationStrategy(@NotNull Editor editor, @NotNull SoftWrapsStorage storage, @NotNull List<CacheEntry> cache) { - super(editor, storage, cache, representationHelper); - mySearchKey = new CacheEntry(0, editor, representationHelper); + super(editor, storage, cache); + mySearchKey = new CacheEntry(0, editor); } public void init(@NotNull final VisualPosition targetVisual, @NotNull final List<CacheEntry> cache) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java index 5541e61f54fb..92ef12c46558 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java @@ -29,6 +29,12 @@ public class TextComponentCaret extends UserDataHolderBase implements Caret { @NotNull @Override + public Editor getEditor() { + return myEditor; + } + + @NotNull + @Override public CaretModel getCaretModel() { return myEditor.getCaretModel(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentEditor.java b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentEditor.java index 80e0cbbc128b..486a7c511016 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentEditor.java @@ -136,7 +136,7 @@ public class TextComponentEditor extends UserDataHolderBase implements Editor { @NotNull public EditorSettings getSettings() { if (mySettings == null) { - mySettings = new SettingsImpl(null); + mySettings = new SettingsImpl(); } return mySettings; } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java index 860ba3211c4b..3519ab6a1af4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java @@ -264,11 +264,11 @@ public class EditorWindow { } public void closeFile(final VirtualFile file) { - closeFile (file, true); + closeFile(file, true); } - public void closeFile(final VirtualFile file, final boolean unsplit) { - closeFile(file, unsplit, true); + public void closeFile(final VirtualFile file, final boolean disposeIfNeeded) { + closeFile(file, disposeIfNeeded, true); } public boolean hasClosedTabs() { @@ -286,7 +286,7 @@ public class EditorWindow { } } - public void closeFile(final VirtualFile file, final boolean unsplit, final boolean transferFocus) { + public void closeFile(final VirtualFile file, final boolean disposeIfNeeded, final boolean transferFocus) { final FileEditorManagerImpl editorManager = getManager(); editorManager.runChange(new FileEditorManagerChange() { @Override @@ -317,13 +317,15 @@ public class EditorWindow { } } - if (unsplit && getTabCount() == 0) { - unsplit (true); + if (disposeIfNeeded && getTabCount() == 0) { + removeFromSplitter(); } - myPanel.revalidate (); - if (myTabbedPane == null) { - // in tabless mode - myPanel.repaint(); + else { + myPanel.revalidate(); + if (myTabbedPane == null) { + // in tabless mode + myPanel.repaint(); + } } } finally { @@ -347,6 +349,39 @@ public class EditorWindow { }, myOwner); } + private void removeFromSplitter() { + if (!inSplitter()) return; + + if (myOwner.getCurrentWindow() == this) { + EditorWindow[] siblings = findSiblings(); + myOwner.setCurrentWindow(siblings[0], false); + } + + Splitter splitter = (Splitter)myPanel.getParent(); + JComponent otherComponent = splitter.getOtherComponent(myPanel); + + Container parent = splitter.getParent().getParent(); + if (parent instanceof Splitter) { + Splitter parentSplitter = (Splitter)parent; + if (parentSplitter.getFirstComponent() == splitter.getParent()) { + parentSplitter.setFirstComponent(otherComponent); + } + else { + parentSplitter.setSecondComponent(otherComponent); + } + } + else if (parent instanceof EditorsSplitters) { + parent.removeAll(); + parent.add(otherComponent, BorderLayout.CENTER); + ((JComponent)parent).revalidate(); + } + else { + throw new IllegalStateException("Unknown container: " + parent); + } + + dispose(); + } + private int calcIndexToSelect(VirtualFile fileBeingClosed, final int fileIndex) { final int currentlySelectedIndex = myTabbedPane.getSelectedIndex(); if (currentlySelectedIndex != fileIndex) { @@ -503,6 +538,8 @@ public class EditorWindow { public void requestFocus(boolean forced) { if (myTabbedPane != null) { myTabbedPane.requestFocus(forced); + } else { + IdeFocusManager.findInstanceByComponent(myPanel).requestFocus(myPanel, forced); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java index 5def1e1fc161..f396b1eed399 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java @@ -173,8 +173,12 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt document.setModificationStamp(file.getModificationStamp()); final FileType fileType = file.getFileType(); document.setReadOnly(!file.isWritable() || fileType.isBinary()); - myDocuments.put(file, document); - document.putUserData(FILE_KEY, file); + if (file instanceof LightVirtualFile) { + registerDocument(document, file); + } else { + myDocuments.put(file, document); + document.putUserData(FILE_KEY, file); + } if (!(file instanceof LightVirtualFile || file.getFileSystem() instanceof DummyFileSystem)) { document.addDocumentListener( diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java index 34be36b69435..9a566e9915ef 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java @@ -314,6 +314,30 @@ public final class IdeKeyEventDispatcher implements Disposable { } } + private static KeyStroke getKeyStrokeWithoutCtrlModifier(KeyStroke originalKeyStroke){ + int modifier=originalKeyStroke.getModifiers()&~InputEvent.CTRL_MASK&~InputEvent.CTRL_DOWN_MASK; + try { + Method[] methods=AWTKeyStroke.class.getDeclaredMethods(); + Method getCachedStrokeMethod=null; + for (Method method : methods) { + if (GET_CACHED_STROKE_METHOD_NAME.equals(method.getName())) { + getCachedStrokeMethod = method; + getCachedStrokeMethod.setAccessible(true); + break; + } + } + if(getCachedStrokeMethod==null){ + throw new IllegalStateException("not found method with name getCachedStrokeMethod"); + } + Object[] getCachedStrokeMethodArgs= + {originalKeyStroke.getKeyChar(), originalKeyStroke.getKeyCode(), modifier, originalKeyStroke.isOnKeyRelease()}; + return (KeyStroke)getCachedStrokeMethod.invoke(originalKeyStroke, getCachedStrokeMethodArgs); + } + catch(Exception exc){ + throw new IllegalStateException(exc.getMessage()); + } + } + private boolean inSecondStrokeInProgressState() { KeyEvent e = myContext.getInputEvent(); @@ -396,6 +420,15 @@ public final class IdeKeyEventDispatcher implements Disposable { KeyStroke originalKeyStroke=KeyStroke.getKeyStrokeForEvent(e); KeyStroke keyStroke=getKeyStrokeWithoutMouseModifiers(originalKeyStroke); + + + if (Registry.is("fix.jdk7.alt.shortcuts") && SystemInfo.isMac && SystemInfo.isOracleJvm && (keyStroke.getModifiers() & InputEvent.ALT_MASK) == InputEvent.ALT_MASK) + { + if (KeymapManager.getInstance().getActiveKeymap().getActionIds(new KeyboardShortcut(keyStroke, null)).length == 0) { + keyStroke = getKeyStrokeWithoutCtrlModifier(keyStroke); + } + } + if (myKeyGestureProcessor.processInitState()) { return true; } @@ -601,7 +634,9 @@ public final class IdeKeyEventDispatcher implements Disposable { processor.onUpdatePassed(e, action, actionEvent); - ((DataManagerImpl.MyDataContext)myContext.getDataContext()).setEventCount(IdeEventQueue.getInstance().getEventCount(), this); + if (myContext.getDataContext() instanceof DataManagerImpl.MyDataContext) { // this is not true for test data contexts + ((DataManagerImpl.MyDataContext)myContext.getDataContext()).setEventCount(IdeEventQueue.getInstance().getEventCount(), this); + } actionManager.fireBeforeActionPerformed(action, actionEvent.getDataContext(), actionEvent); Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(actionEvent.getDataContext()); if (component != null && !component.isShowing()) { diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java index 4c093211cfd6..7b4f5a0371ba 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.intellij.openapi.keymap.impl; +import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; @@ -27,6 +28,7 @@ import com.intellij.openapi.options.SchemesManager; import com.intellij.openapi.options.SchemesManagerFactory; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.registry.Registry; import com.intellij.util.containers.ContainerUtil; import org.jdom.Document; import org.jdom.Element; @@ -35,6 +37,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.awt.event.KeyEvent; import java.io.File; import java.io.IOException; import java.util.*; @@ -92,6 +95,14 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat } } load(); + + if (Registry.is("editor.add.carets.on.double.control.arrows")) { + ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_CLONE_CARET_ABOVE, KeyEvent.VK_CONTROL, KeyEvent.VK_UP); + ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW, KeyEvent.VK_CONTROL, KeyEvent.VK_DOWN); + ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT, KeyEvent.VK_CONTROL, KeyEvent.VK_LEFT); + ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT, KeyEvent.VK_CONTROL, KeyEvent.VK_RIGHT); + } + ourKeymapManagerInitialized = true; } diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java new file mode 100644 index 000000000000..28536453b713 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java @@ -0,0 +1,210 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.keymap.impl; + +import com.intellij.ide.DataManager; +import com.intellij.ide.IdeEventQueue; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.util.Clock; +import com.intellij.openapi.util.Couple; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.util.containers.ConcurrentHashMap; +import gnu.trove.TIntIntHashMap; +import gnu.trove.TIntIntProcedure; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Support for keyboard shortcuts like Control-double-click or Control-double-click+A + */ +public class ModifierKeyDoubleClickHandler { + private static final ModifierKeyDoubleClickHandler INSTANCE = new ModifierKeyDoubleClickHandler(); + + private final ConcurrentMap<String, IdeEventQueue.EventDispatcher> myDispatchers = new ConcurrentHashMap<String, IdeEventQueue.EventDispatcher>(); + + private ModifierKeyDoubleClickHandler() { } + + public static ModifierKeyDoubleClickHandler getInstance() { + return INSTANCE; + } + + /** + * @param actionId Id of action to be triggered on modifier+modifier[+actionKey] + * @param modifierKeyCode keyCode for modifier, e.g. KeyEvent.VK_SHIFT + * @param actionKeyCode keyCode for actionKey, or -1 if action should be triggered on bare modifier double click + */ + public void registerAction(@NotNull String actionId, + int modifierKeyCode, + int actionKeyCode) { + final MyDispatcher dispatcher = new MyDispatcher(actionId, modifierKeyCode, actionKeyCode); + IdeEventQueue.EventDispatcher oldDispatcher = myDispatchers.put(actionId, dispatcher); + IdeEventQueue.getInstance().addDispatcher(dispatcher, null); + if (oldDispatcher != null) { + IdeEventQueue.getInstance().removeDispatcher(oldDispatcher); + } + } + + public void unregisterAction(@NotNull String actionId) { + IdeEventQueue.EventDispatcher oldDispatcher = myDispatchers.remove(actionId); + if (oldDispatcher != null) { + IdeEventQueue.getInstance().removeDispatcher(oldDispatcher); + } + } + + private static class MyDispatcher implements IdeEventQueue.EventDispatcher { + private static final TIntIntHashMap KEY_CODE_TO_MODIFIER_MAP = new TIntIntHashMap(); + static { + KEY_CODE_TO_MODIFIER_MAP.put(KeyEvent.VK_ALT, InputEvent.ALT_MASK); + KEY_CODE_TO_MODIFIER_MAP.put(KeyEvent.VK_CONTROL, InputEvent.CTRL_MASK); + KEY_CODE_TO_MODIFIER_MAP.put(KeyEvent.VK_META, InputEvent.META_MASK); + KEY_CODE_TO_MODIFIER_MAP.put(KeyEvent.VK_SHIFT, InputEvent.SHIFT_MASK); + } + + private final String myActionId; + private final int myModifierKeyCode; + private final int myActionKeyCode; + + private final Couple<AtomicBoolean> ourPressed = Couple.of(new AtomicBoolean(false), new AtomicBoolean(false)); + private final Couple<AtomicBoolean> ourReleased = Couple.of(new AtomicBoolean(false), new AtomicBoolean(false)); + private final AtomicBoolean ourOtherKeyWasPressed = new AtomicBoolean(false); + private final AtomicLong ourLastTimePressed = new AtomicLong(0); + + public MyDispatcher(@NotNull String actionId, int modifierKeyCode, int actionKeyCode) { + myActionId = actionId; + myModifierKeyCode = modifierKeyCode; + myActionKeyCode = actionKeyCode; + } + + @Override + public boolean dispatch(AWTEvent event) { + if (event instanceof KeyEvent) { + final KeyEvent keyEvent = (KeyEvent)event; + final int keyCode = keyEvent.getKeyCode(); + + if (keyCode == myModifierKeyCode) { + if (hasOtherModifiers(keyEvent)) { + resetState(); + return false; + } + if (ourOtherKeyWasPressed.get() && Clock.getTime() - ourLastTimePressed.get() < 500) { + resetState(); + return false; + } + ourOtherKeyWasPressed.set(false); + if (ourPressed.first.get() && Clock.getTime() - ourLastTimePressed.get() > 500) { + resetState(); + } + handleModifier((KeyEvent)event); + return false; + } else if (ourPressed.first.get() && ourReleased.first.get() && ourPressed.second.get() && myActionKeyCode != -1) { + if (keyCode == myActionKeyCode) { + if (event.getID() == KeyEvent.KEY_RELEASED) { + run(keyEvent); + } + return true; + } + return false; + } else { + ourLastTimePressed.set(Clock.getTime()); + ourOtherKeyWasPressed.set(true); + if (keyCode == KeyEvent.VK_ESCAPE || keyCode == KeyEvent.VK_TAB) { + ourLastTimePressed.set(0); + } + } + resetState(); + } + return false; + } + + private boolean hasOtherModifiers(KeyEvent keyEvent) { + final int modifiers = keyEvent.getModifiers(); + return !KEY_CODE_TO_MODIFIER_MAP.forEachEntry(new TIntIntProcedure() { + @Override + public boolean execute(int keyCode, int modifierMask) { + return keyCode == myModifierKeyCode || (modifiers & modifierMask) == 0; + } + }); + } + + private void handleModifier(KeyEvent event) { + if (ourPressed.first.get() && Clock.getTime() - ourLastTimePressed.get() > 300) { + resetState(); + return; + } + + if (event.getID() == KeyEvent.KEY_PRESSED) { + if (!ourPressed.first.get()) { + resetState(); + ourPressed.first.set(true); + ourLastTimePressed.set(Clock.getTime()); + return; + } else { + if (ourPressed.first.get() && ourReleased.first.get()) { + ourPressed.second.set(true); + ourLastTimePressed.set(Clock.getTime()); + return; + } + } + } else if (event.getID() == KeyEvent.KEY_RELEASED) { + if (ourPressed.first.get() && !ourReleased.first.get()) { + ourReleased.first.set(true); + ourLastTimePressed.set(Clock.getTime()); + return; + } else if (ourPressed.first.get() && ourReleased.first.get() && ourPressed.second.get()) { + resetState(); + if (myActionKeyCode == -1 && !isActionBound()) { + run(event); + } + return; + } + } + resetState(); + } + + private void resetState() { + ourPressed.first.set(false); + ourPressed.second.set(false); + ourReleased.first.set(false); + ourReleased.second.set(false); + } + + private void run(KeyEvent event) { + final ActionManager actionManager = ActionManager.getInstance(); + final AnAction action = actionManager.getAction(myActionId); + final AnActionEvent anActionEvent = new AnActionEvent(event, + DataManager.getInstance().getDataContext(IdeFocusManager.findInstance().getFocusOwner()), + ActionPlaces.MAIN_MENU, + action.getTemplatePresentation(), + actionManager, + 0); + action.actionPerformed(anActionEvent); + } + + private boolean isActionBound() { + return KeymapManager.getInstance().getActiveKeymap().getShortcuts(myActionId).length > 0; + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java b/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java new file mode 100644 index 000000000000..104dc7b30ec7 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java @@ -0,0 +1,52 @@ +package com.intellij.openapi.options; + +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public abstract class ConfigurableBase<UI extends ConfigurableUi<S>, S> implements SearchableConfigurable, Configurable.NoScroll { + private UI ui; + + @Nullable + @Override + public Runnable enableSearch(String option) { + return null; + } + + protected abstract S getSettings(); + + @Override + public void reset() { + if (ui != null) { + ui.reset(getSettings()); + } + } + + @Nullable + @Override + public final JComponent createComponent() { + if (ui == null) { + ui = createUi(); + } + return ui.getComponent(); + } + + protected abstract UI createUi(); + + @Override + public final boolean isModified() { + return ui != null && ui.isModified(getSettings()); + } + + @Override + public final void apply() { + if (ui != null) { + ui.apply(getSettings()); + } + } + + @Override + public void disposeUIResources() { + ui = null; + } +}
\ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java b/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java new file mode 100644 index 000000000000..e454099318ea --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java @@ -0,0 +1,16 @@ +package com.intellij.openapi.options; + +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +public interface ConfigurableUi<S> { + void reset(@NotNull S settings); + + boolean isModified(@NotNull S settings); + + void apply(@NotNull S settings); + + @NotNull + JComponent getComponent(); +}
\ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java index ed72e27e8c22..5f8dc0e890df 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java @@ -47,8 +47,17 @@ public class ConfigurableWrapper implements SearchableConfigurable { @Nullable public static <T extends UnnamedConfigurable> T wrapConfigurable(ConfigurableEP<T> ep) { - if (ep.displayName != null || ep.key != null) { - return (T)(ep.children != null || ep.childrenEPName != null || ep.dynamic ? new CompositeWrapper(ep) : new ConfigurableWrapper(ep)); + if (ep.displayName != null || ep.key != null || ep.groupId != null) { + T configurable = null; + if (ep.providerClass != null) { + configurable = ep.createConfigurable(); + if (configurable == null) { + return null; // it is allowed to return null from provider + } + } + return ep.children != null || ep.childrenEPName != null || ep.dynamic + ? (T)new CompositeWrapper(ep, configurable) + : (T)new ConfigurableWrapper(ep, configurable); } else { return ep.createConfigurable(); @@ -76,8 +85,9 @@ public class ConfigurableWrapper implements SearchableConfigurable { private final ConfigurableEP myEp; - private ConfigurableWrapper(@NotNull ConfigurableEP ep) { + private ConfigurableWrapper(@NotNull ConfigurableEP ep, @Nullable UnnamedConfigurable configurable) { myEp = ep; + myConfigurable = configurable; } private UnnamedConfigurable myConfigurable; @@ -95,6 +105,12 @@ public class ConfigurableWrapper implements SearchableConfigurable { @Nls @Override public String getDisplayName() { + if (myEp.displayName == null && myEp.key == null) { + UnnamedConfigurable configurable = getConfigurable(); + if (configurable instanceof Configurable) { + return ((Configurable)configurable).getDisplayName(); + } + } return myEp.getDisplayName(); } @@ -141,16 +157,24 @@ public class ConfigurableWrapper implements SearchableConfigurable { @NotNull @Override public String getId() { - return myEp.id == null ? myEp.instanceClass : myEp.id; + return myEp.id == null ? myEp.instanceClass == null ? myEp.providerClass : myEp.instanceClass : myEp.id; } + @NotNull + public ConfigurableEP getExtensionPoint() { + return myEp; + } + + public String getGroupId() { + return myEp.groupId; + } public String getParentId() { return myEp.parentId; } public ConfigurableWrapper addChild(Configurable configurable) { - return new CompositeWrapper(myEp, configurable); + return new CompositeWrapper(myEp, null, configurable); } @Override @@ -169,8 +193,8 @@ public class ConfigurableWrapper implements SearchableConfigurable { private Configurable[] myKids; - private CompositeWrapper(ConfigurableEP ep, Configurable... kids) { - super(ep); + private CompositeWrapper(@NotNull ConfigurableEP ep, @Nullable UnnamedConfigurable configurable, Configurable... kids) { + super(ep, configurable); if (ep.dynamic) { kids = ((Composite)getConfigurable()).getConfigurables(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java new file mode 100644 index 000000000000..f465e2d0fecb --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java @@ -0,0 +1,83 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.options.ex; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurableGroup; +import com.intellij.openapi.options.OptionsBundle; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map.Entry; + +public final class MixedConfigurableGroup implements ConfigurableGroup { + private final String myGroupId; + private Configurable[] myConfigurables; + + private MixedConfigurableGroup(String groupId, ArrayList<Configurable> configurables) { + myGroupId = groupId; + myConfigurables = (configurables != null) + ? configurables.toArray(new Configurable[configurables.size()]) + : new Configurable[0]; + } + + private MixedConfigurableGroup(String groupId, HashMap<String, ArrayList<Configurable>> configurables) { + this(groupId, configurables.remove(groupId)); + } + + @Override + public String getDisplayName() { + return OptionsBundle.message("configurable.group." + myGroupId + ".settings.display.name"); + } + + @Override + public String getShortName() { + return getDisplayName(); + } + + @Override + public Configurable[] getConfigurables() { + return myConfigurables; + } + + public static ConfigurableGroup[] getGroups(Configurable... configurables) { + HashMap<String, ArrayList<Configurable>> map = new HashMap<String, ArrayList<Configurable>>(); + for (Configurable configurable : configurables) { + String groupId = null; + if (configurable instanceof ConfigurableWrapper) { + groupId = ((ConfigurableWrapper)configurable).getGroupId(); + } + ArrayList<Configurable> list = map.get(groupId); + if (list == null) { + map.put(groupId, list = new ArrayList<Configurable>()); + } + list.add(configurable); + } + ArrayList<ConfigurableGroup> groups = new ArrayList<ConfigurableGroup>(map.size()); + groups.add(new MixedConfigurableGroup("appearance", map)); + groups.add(new MixedConfigurableGroup("editor", map)); + groups.add(new MixedConfigurableGroup("project", map)); + groups.add(new MixedConfigurableGroup("build", map)); + groups.add(new MixedConfigurableGroup("language", map)); + groups.add(new MixedConfigurableGroup("tools", map)); + ConfigurableGroup other = new MixedConfigurableGroup(null, map); + for(Entry<String, ArrayList<Configurable>>entry: map.entrySet()){ + groups.add(new MixedConfigurableGroup(entry.getKey(), entry.getValue())); + } + groups.add(other); + return groups.toArray(new ConfigurableGroup[groups.size()]); + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java index bd843131e16a..5524df2bb2cb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,19 @@ */ package com.intellij.openapi.options.newEditor; +import com.intellij.icons.AllIcons; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.Disposable; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableGroup; +import com.intellij.openapi.options.OptionsBundle; import com.intellij.openapi.options.SearchableConfigurable; +import com.intellij.openapi.options.ex.ConfigurableWrapper; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.*; import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.treeStructure.*; @@ -287,7 +291,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl class Renderer extends GroupedElementsRenderer.Tree { - + private JLabel myProjectIcon; private JLabel myHandle; @Override @@ -304,6 +308,9 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl myHandle.setOpaque(false); content.add(myHandle, BorderLayout.WEST); content.add(myComponent, BorderLayout.CENTER); + myProjectIcon = new JLabel(" ", AllIcons.General.ProjectConfigurable, SwingConstants.LEFT); + myProjectIcon.setOpaque(true); + content.add(myProjectIcon, BorderLayout.EAST); myRendererComponent.add(content, BorderLayout.CENTER); } @@ -393,10 +400,39 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl myTextLabel.setForeground(selected ? UIUtil.getTreeSelectionForeground() : fg); myTextLabel.setOpaque(selected); + if (Registry.is("ide.file.settings.order.new")) { + myTextLabel.setBorder(new EmptyBorder(1,2,1,0)); + } + Project project = getConfigurableProject(base); + if (project != null && Registry.is("ide.file.settings.order.new")) { + myProjectIcon.setBackground(selected ? getSelectionBackground() : getBackground()); + myProjectIcon.setVisible(true); + tree.setToolTipText(OptionsBundle.message(project.isDefault() + ? "configurable.default.project.tooltip" + : "configurable.current.project.tooltip")); + } else { + myProjectIcon.setVisible(false); + tree.setToolTipText(null); + } return result; } + private Project getConfigurableProject(SimpleNode node) { + if (node == null) { + return null; + } + if (node instanceof EditorNode) { + EditorNode editor = (EditorNode)node; + Configurable configurable = editor.getConfigurable(); + if (configurable instanceof ConfigurableWrapper) { + ConfigurableWrapper wrapper = (ConfigurableWrapper)configurable; + return wrapper.getExtensionPoint().getProject(); + } + } + return getConfigurableProject(node.getParent()); + } + protected JComponent createItemComponent() { myTextLabel = new ErrorLabel(); return myTextLabel; @@ -602,6 +638,12 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl private MyTree() { getInputMap().clear(); + setOpaque(true); + } + + @Override + protected boolean paintNodes() { + return false; } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index c79e4118f36c..2f95c21cb558 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -752,8 +752,11 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt message = ProjectBundle.message("project.reload.external.change.multiple", filesBuilder.toString()); } - return Messages.showTwoStepConfirmationDialog(message, ProjectBundle.message("project.reload.external.change.title"), "Reload project", - Messages.getQuestionIcon()) == 0; + return Messages.showDialog(message, + ProjectBundle.message("project.reload.external.change.title"), + new String[]{"&Reload Project", "&Discard Changes"}, + -1, + Messages.getQuestionIcon()) == 0; } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoPanel.form b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoPanel.form index 167e5ef8ab00..0e86badb08c5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoPanel.form +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoPanel.form @@ -20,7 +20,7 @@ <grid id="3559e" binding="myPluginsPanel" layout-manager="BorderLayout" hgap="0" vgap="0"> <constraints> <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> - <gridbag top="3" left="0" bottom="3" right="0" weightx="1.0" weighty="0.0"/> + <gridbag top="3" left="0" bottom="3" right="0" weightx="1.0" weighty="1.0"/> </constraints> <properties> <autoscrolls value="false"/> @@ -41,12 +41,6 @@ <contentType value="text/html"/> </properties> </component> - <vspacer id="bf1d9"> - <constraints> - <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> - <gridbag weightx="0.0" weighty="1.0"/> - </constraints> - </vspacer> </children> </grid> </form> diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java index f7346548124a..8d00a82d4814 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java @@ -120,9 +120,6 @@ public class FileWatcher { } }); } - else if (!isUpToDate(myExecutable)) { - notifyOnFailure(ApplicationBundle.message("watcher.exe.outdated"), null); - } else { try { startupProcess(false); @@ -181,30 +178,16 @@ public class FileWatcher { @Nullable private static File getExecutable() { - String execPath = null; - - final String altExecPath = System.getProperty(PROPERTY_WATCHER_EXECUTABLE_PATH); - if (altExecPath != null && new File(altExecPath).isFile()) { - execPath = FileUtil.toSystemDependentName(altExecPath); - } + String execPath = System.getProperty(PROPERTY_WATCHER_EXECUTABLE_PATH); + if (execPath != null) return new File(execPath); - if (execPath == null) { - final String execName = getExecutableName(false); - if (execName == null) { - return null; - } - execPath = FileUtil.join(PathManager.getBinPath(), execName); - } + String execName = getExecutableName(false); + if (execName == null) return null; - File exec = new File(execPath); - if (!exec.exists()) { - String homePath = PathManager.getHomePath(); - if (new File(homePath, "community").exists()) { - homePath += File.separator + "community"; - } - exec = new File(FileUtil.join(homePath, "bin", getExecutableName(true))); - } - return exec; + return FileUtil.findFirstThatExist( + FileUtil.join(PathManager.getBinPath(), execName), + FileUtil.join(PathManager.getHomePath(), "community", "bin", getExecutableName(true)), + FileUtil.join(PathManager.getBinPath(), getExecutableName(true))); } @Nullable @@ -215,14 +198,6 @@ public class FileWatcher { return null; } - private static boolean isUpToDate(File executable) { - long length = SystemInfo.isWindows ? 71208 : - SystemInfo.isMac ? 13984 : - SystemInfo.isLinux ? SystemInfo.isAMD64 ? 29155 : 22791 : - -1; - return length < 0 || length == executable.length(); - } - public void notifyOnFailure(final String cause, @Nullable final NotificationListener listener) { LOG.warn(cause); @@ -580,8 +555,11 @@ public class FileWatcher { case CREATE: case DELETE: for (String p : paths) { + myDirtyPaths.dirtyPaths.add(p); String parentPath = new File(p).getParent(); - myDirtyPaths.dirtyPaths.add(parentPath != null ? parentPath : p); + if (parentPath != null) { + myDirtyPaths.dirtyPaths.add(parentPath); + } } break; diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java index 72cd066472c6..b05b7a285e7b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java @@ -1338,7 +1338,11 @@ public class FSRecords implements Forceable { private static final MessageDigest myDigest = ContentHashesUtil.createHashDigest(); public static void writeContent(int fileId, ByteSequence bytes, boolean readOnly) throws IOException { - new ContentOutputStream(fileId, readOnly).writeBytes(bytes); + try { + new ContentOutputStream(fileId, readOnly).writeBytes(bytes); + } catch (Throwable e) { + throw DbConnection.handleError(e); + } } public static int storeUnlinkedContent(byte[] bytes) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index 36a79f23cf89..c302cce7572e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -195,7 +195,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { @Override @NotNull public ActionCallback requestFocus(@NotNull final Component c, final boolean forced) { - return requestFocus(new FocusCommand.ByComponent(c), forced); + return requestFocus(new FocusCommand.ByComponent(c, new Exception()), forced); } @Override @@ -1148,7 +1148,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } if (toFocus != null) { - return requestFocus(new FocusCommand.ByComponent(toFocus).setToInvalidateRequestors(false), forced); + return requestFocus(new FocusCommand.ByComponent(toFocus, new Exception()).setToInvalidateRequestors(false), forced); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java index 7d534d5be545..f62ff2c1819a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java @@ -30,6 +30,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.ToolWindowAnchor; import com.intellij.ui.MouseDragHelper; import com.intellij.ui.PopupHandler; +import com.intellij.util.ui.JBImageIcon; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -183,12 +184,22 @@ public final class StripeButton extends AnchoredButton implements ActionListener if (myDragPane == null) return; final BufferedImage image = UIUtil.createImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); paint(image.getGraphics()); - myDragButtonImage = new JLabel(new ImageIcon(image)) { + myDragButtonImage = new JLabel(new JBImageIcon(image)) { public String toString() { return "Image for: " + StripeButton.this.toString(); } }; + + myDragButtonImage.addMouseListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + finishDragging(); + myPressedPoint = null; + myDragButtonImage = null; + super.mouseReleased(e); + } + }); myDragPane.add(myDragButtonImage, JLayeredPane.POPUP_LAYER); myDragButtonImage.setSize(myDragButtonImage.getPreferredSize()); setVisible(false); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/TestWindowManager.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/TestWindowManager.java index b2fc056d0a71..aa7d022a4b5e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/TestWindowManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/TestWindowManager.java @@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.BalloonHandler; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.StatusBar; @@ -38,14 +39,16 @@ import javax.swing.event.HyperlinkListener; import java.awt.*; import java.awt.event.ComponentEvent; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author Anton Katilin * @author Vladimir Kondratyev */ public final class TestWindowManager extends WindowManagerEx { - private static final StatusBarEx ourStatusBar = new DummyStatusBar(); + private static final Key<StatusBar> STATUS_BAR = Key.create("STATUS_BAR"); public final void doNotSuggestAsParent(final Window window) { } @@ -66,7 +69,13 @@ public final class TestWindowManager extends WindowManagerEx { @Override public final StatusBar getStatusBar(final Project project) { - return ourStatusBar; + synchronized (STATUS_BAR) { + StatusBar statusBar = project.getUserData(STATUS_BAR); + if (statusBar == null) { + project.putUserData(STATUS_BAR, statusBar = new DummyStatusBar()); + } + return statusBar; + } } @Override @@ -86,6 +95,8 @@ public final class TestWindowManager extends WindowManagerEx { public void resetWindow(final Window window) { } private static final class DummyStatusBar implements StatusBarEx { + private final Map<String, StatusBarWidget> myWidgetMap = new HashMap<String, StatusBarWidget>(); + @Override public Dimension getSize() { return new Dimension(0, 0); @@ -140,33 +151,39 @@ public final class TestWindowManager extends WindowManagerEx { } @Override + public void addWidget(@NotNull StatusBarWidget widget) { + myWidgetMap.put(widget.ID(), widget); + } + + @Override + public void addWidget(@NotNull StatusBarWidget widget, @NotNull String anchor) { + addWidget(widget); + } + + @Override public void addWidget(@NotNull StatusBarWidget widget, @NotNull Disposable parentDisposable) { Disposer.register(parentDisposable, widget); + addWidget(widget); } @Override public void addWidget(@NotNull StatusBarWidget widget, @NotNull String anchor, @NotNull Disposable parentDisposable) { Disposer.register(parentDisposable, widget); + addWidget(widget); } @Override public void updateWidgets() { } @Override - public void addWidget(@NotNull StatusBarWidget widget) { } - - @Override public void dispose() { } @Override - public void addWidget(@NotNull StatusBarWidget widget, @NotNull String anchor) { } - - @Override public void updateWidget(@NotNull String id) { } @Override public StatusBarWidget getWidget(String id) { - return null; + return myWidgetMap.get(id); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java index ae1e5336e9fe..efcdd148d57b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java @@ -357,7 +357,7 @@ public final class ToolWindowImpl implements ToolWindowEx { ApplicationManager.getApplication().assertIsDispatchThread(); final Icon oldIcon = getIcon(); if (oldIcon != icon && !(icon instanceof LayeredIcon) && (icon.getIconHeight() != 13 || icon.getIconWidth() != 13)) { - LOG.warn("ToolWindow icons should be 13x13. Please fix " + icon); + LOG.warn("ToolWindow icons should be 13x13. Please fix ToolWindow (ID: " + getId() + ") or icon " + icon); } getSelectedContent().setIcon(icon); myIcon = icon; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInToolWindowCmd.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInToolWindowCmd.java index d58d3b914849..c8f542133149 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInToolWindowCmd.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInToolWindowCmd.java @@ -184,7 +184,7 @@ public final class RequestFocusInToolWindowCmd extends FinalizableCommand { }).notify(result); } else { - myManager.getFocusManager().requestFocus(new FocusCommand.ByComponent(c, myToolWindow.getComponent()), myForced) + myManager.getFocusManager().requestFocus(new FocusCommand.ByComponent(c, myToolWindow.getComponent(), new Exception()), myForced) .doWhenProcessed(new Runnable() { @Override public void run() { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java index 84b6e6a7e0ce..e00c195be9ce 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java @@ -368,7 +368,8 @@ public class InfoAndProgressPanel extends JPanel implements CustomStatusBarWidge myRefreshAndInfoPanel.revalidate(); myRefreshAndInfoPanel.repaint(); - if (UISettings.getInstance().PRESENTATION_MODE) { + UISettings uiSettings = UISettings.getInstance(); + if (uiSettings.PRESENTATION_MODE || !uiSettings.SHOW_STATUS_BAR && Registry.is("ide.show.progress.without.status.bar")) { final JRootPane pane = myInfoPanel.getRootPane(); final RelativePoint point = new RelativePoint(pane, new Point(pane.getWidth() - 250, 60)); final PresentationModeProgressPanel panel = new PresentationModeProgressPanel(inline); diff --git a/platform/platform-impl/src/com/intellij/remote/PathMappingProvider.java b/platform/platform-impl/src/com/intellij/remote/PathMappingProvider.java index 2d4a76f1df1c..4e5482d3d422 100644 --- a/platform/platform-impl/src/com/intellij/remote/PathMappingProvider.java +++ b/platform/platform-impl/src/com/intellij/remote/PathMappingProvider.java @@ -5,7 +5,6 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; import com.intellij.util.PathMappingSettings; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,8 +32,4 @@ public abstract class PathMappingProvider { @NotNull public abstract PathMappingSettings getPathMappingSettings(@NotNull Project project, @NotNull RemoteSdkAdditionalData data); - - @Deprecated //Remove in IDEA 14 - @NotNull - public abstract PathMappingSettings getPathMapping(@NotNull Project project, @NotNull com.intellij.remotesdk.RemoteSdkAdditionalData data); } diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteFile.java b/platform/platform-impl/src/com/intellij/remote/RemoteFile.java index 4a2e11379364..724ec31fe1ef 100644 --- a/platform/platform-impl/src/com/intellij/remote/RemoteFile.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteFile.java @@ -2,7 +2,6 @@ package com.intellij.remote; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author traff @@ -25,14 +24,14 @@ public class RemoteFile { this(resolveChild(parent, child, isWin), isWin); } - @Nullable + @NotNull public String getName() { int ind = myPath.lastIndexOf(getSeparator(myWin)); if (ind != -1 && ind < myPath.length() - 1) { //not last char return myPath.substring(ind + 1); } else { - return null; + return myPath; } } @@ -88,6 +87,10 @@ public class RemoteFile { return detectSystemByPath(path).createRemoteFile(path, script); } + public static RemoteFile createRemoteFile(String path) { + return detectSystemByPath(path).createRemoteFile(path); + } + public static RemoteFile createRemoteFile(final String path, final String script, final boolean isWindows) { return new RemoteFileBuilder(isWindows).createRemoteFile(path, script); } diff --git a/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java b/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java deleted file mode 100644 index 0b630fec6a8b..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/MutableRemoteCredentials.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -/** - * @deprecated Remove in IDEA 14 - * @author traff - */ -public interface MutableRemoteCredentials extends com.intellij.remote.MutableRemoteCredentials { -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java deleted file mode 100644 index 2a249209b8e8..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCancelledException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -/** - * @deprecated Remove in IDEA 14 - * - * @author traff - */ -public class RemoteCancelledException extends com.intellij.remote.RemoteCancelledException { - public RemoteCancelledException(String s) { - super(s); - } -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java deleted file mode 100644 index e6be766ca826..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentials.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -/** - * @deprecated Remove in IDEA 14 - * - * @author traff - */ -public interface RemoteCredentials extends com.intellij.remote.RemoteCredentials { -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java deleted file mode 100644 index 886052957f32..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteCredentialsHolder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -/** - * @deprecated Remove in IDEA 14 - * - * @author traff - */ -public class RemoteCredentialsHolder extends com.intellij.remote.RemoteCredentialsHolder { -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java deleted file mode 100644 index 73274cc0f356..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteFile.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -import org.jetbrains.annotations.NotNull; - -/** - * @deprecated Remove in IDEA 14 - * - * @author traff - */ -public class RemoteFile extends com.intellij.remote.RemoteFile { - - public RemoteFile(@NotNull String path, boolean isWin) { - super(path, isWin); - } - - public RemoteFile(@NotNull String parent, String child) { - super(parent, child); - } - - public RemoteFile(@NotNull String parent, String child, boolean isWin) { - super(parent, child, isWin); - } -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java deleted file mode 100644 index a83d2bdc2455..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteProcessHandlerBase.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -/** - * @deprecated Remove in IDEA 14 - * - * @author traff - */ -public interface RemoteProcessHandlerBase extends com.intellij.remote.RemoteProcessHandlerBase { -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java deleted file mode 100644 index e4c79ed8d7f2..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkAdditionalData.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.intellij.remotesdk; - -import com.intellij.openapi.projectRoots.SdkAdditionalData; -import com.intellij.remote.RemoteSdkCredentials; - -/** - * @deprecated Remove in IDEA 14 - * @author traff - */ -public interface RemoteSdkAdditionalData extends RemoteSdkCredentials, SdkAdditionalData { - void completeInitialization(); -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkData.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkData.java deleted file mode 100644 index d99ea338db00..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkData.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -import com.intellij.remote.RemoteSdkCredentials; - -/** - * @deprecated Remove in IDEA 14 - * - * @author traff - */ -public interface RemoteSdkData extends RemoteSdkCredentials { -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataBuilder.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataBuilder.java deleted file mode 100644 index f2dd26589392..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataBuilder.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -import com.intellij.remote.RemoteSdkCredentialsBuilder; - -/** - * @deprecated Remove in IDEA 14 - * - * @author traff - */ -public class RemoteSdkDataBuilder extends RemoteSdkCredentialsBuilder { -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataHolder.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataHolder.java deleted file mode 100644 index b4f837c72a3f..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkDataHolder.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -import com.intellij.remote.RemoteSdkCredentialsHolder; -import org.jetbrains.annotations.NotNull; - -/** - * @deprecated Remove in IDEA 14 - * - * @author traff - */ -public class RemoteSdkDataHolder extends RemoteSdkCredentialsHolder { - public RemoteSdkDataHolder(@NotNull String defaultHelpersDirName) { - super(defaultHelpersDirName); - } -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java deleted file mode 100644 index 1934d1aa36a2..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSdkFactory.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.remote.RemoteSdkException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.awt.*; -import java.util.Collection; - -/** - * @deprecated Remove in IDEA 14 - * @author traff - */ -public interface RemoteSdkFactory<T extends RemoteSdkAdditionalData> { - Sdk createRemoteSdk(@Nullable Project project, @NotNull T data, @Nullable String sdkName, Collection<Sdk> existingSdks) - throws RemoteInterpreterException; - - Sdk createUnfinished(T data, Collection<Sdk> existingSdks); - - String getDefaultUnfinishedName(); - - @NotNull - String sdkName(); - - boolean canSaveUnfinished(); - - void initSdk(@NotNull Sdk sdk, @Nullable Project project, @Nullable Component ownerComponent); -} diff --git a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java b/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java deleted file mode 100644 index 3abe39bd1aba..000000000000 --- a/platform/platform-impl/src/com/intellij/remotesdk/RemoteSshProcess.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.remotesdk; - -/** - * @deprecated Remove in IDEA 14 - * @author traff - */ -public abstract class RemoteSshProcess extends com.intellij.remote.RemoteSshProcess { -} diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java index 7226ee84e0c6..4e65063e7939 100644 --- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java +++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java @@ -54,6 +54,16 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte myTipComponent = new TipComponent(); + myTipComponent.addMouseListener(new MouseAdapter() { + @Override + public void mouseExited(MouseEvent e) { + // don't hide the hint if mouse exited to myComponent + if (myComponent.getMousePosition() == null) { + hideHint(); + } + } + }); + myComponent.addMouseListener( new MouseListener() { @Override @@ -63,7 +73,10 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte @Override public void mouseExited(MouseEvent e) { - hideHint(); + // don't hide the hint if mouse exited to it + if (myTipComponent.getMousePosition() == null) { + hideHint(); + } } @Override @@ -319,7 +332,7 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte g.setClip(null); doFillBackground(height, width, g); g.translate(-(visibleRect.x + visibleRect.width - cellBounds.x), 0); - doPaintTooltipImage(renderer, cellBounds, height, g, key); + doPaintTooltipImage(renderer, cellBounds, g, key); if (isPaintBorder()) { g.translate(visibleRect.x + visibleRect.width - cellBounds.x, 0); @@ -354,8 +367,8 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte g.fillRect(0, 0, width, height); } - protected void doPaintTooltipImage(Component rComponent, Rectangle cellBounds, int height, Graphics2D g, KeyType key) { - myRendererPane.paintComponent(g, rComponent, myComponent, 0, 0, cellBounds.width, height, true); + protected void doPaintTooltipImage(Component rComponent, Rectangle cellBounds, Graphics2D g, KeyType key) { + myRendererPane.paintComponent(g, rComponent, myComponent, 0, 0, cellBounds.width, cellBounds.height, true); } protected Rectangle getVisibleRect(KeyType key) { diff --git a/platform/platform-impl/src/com/intellij/ui/CellRendererPanel.java b/platform/platform-impl/src/com/intellij/ui/CellRendererPanel.java index 2c33b7cd1b61..653aba26dae8 100644 --- a/platform/platform-impl/src/com/intellij/ui/CellRendererPanel.java +++ b/platform/platform-impl/src/com/intellij/ui/CellRendererPanel.java @@ -25,6 +25,9 @@ import java.awt.*; * @author gregsh */ public class CellRendererPanel extends JPanel { + public CellRendererPanel() { + super(null); // we do the layout ourselves + } // property change support ---------------- protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { @@ -46,7 +49,10 @@ public class CellRendererPanel extends JPanel { @Override public void doLayout() { if (getComponentCount() != 1) return; - getComponent(0).setBounds(0, 0, getWidth(), getHeight()); + Insets insets = getInsets(); + getComponent(0).setBounds(insets.left, insets.top, + getWidth() - insets.left - insets.right, + getHeight() - insets.top - insets.bottom); } @Override diff --git a/platform/platform-impl/src/com/intellij/ui/ColorChooserServiceImpl.java b/platform/platform-impl/src/com/intellij/ui/ColorChooserServiceImpl.java index 4bc4213a78ec..355c2a8de3e3 100644 --- a/platform/platform-impl/src/com/intellij/ui/ColorChooserServiceImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/ColorChooserServiceImpl.java @@ -15,10 +15,11 @@ */ package com.intellij.ui; -import com.intellij.psi.PsiElement; import org.jetbrains.annotations.Nullable; import java.awt.*; +import java.util.Arrays; +import java.util.List; /** * @author Konstantin Bulenkov @@ -31,7 +32,7 @@ public class ColorChooserServiceImpl extends ColorChooserService { Color preselectedColor, boolean enableOpacity, ColorPickerListener[] listeners) { - return ColorPicker.showDialog(parent, caption, preselectedColor, enableOpacity, listeners, false); + return showDialog(parent, caption, preselectedColor, enableOpacity, Arrays.asList(listeners), false); } @Nullable @@ -42,6 +43,17 @@ public class ColorChooserServiceImpl extends ColorChooserService { boolean enableOpacity, ColorPickerListener[] listeners, boolean opacityInPercent) { + return showDialog(parent, caption, preselectedColor, enableOpacity, Arrays.asList(listeners), opacityInPercent); + } + + @Nullable + @Override + public Color showDialog(Component parent, + String caption, + Color preselectedColor, + boolean enableOpacity, + List<ColorPickerListener> listeners, + boolean opacityInPercent) { return ColorPicker.showDialog(parent, caption, preselectedColor, enableOpacity, listeners, opacityInPercent); } } diff --git a/platform/platform-impl/src/com/intellij/ui/ColorPicker.java b/platform/platform-impl/src/com/intellij/ui/ColorPicker.java index d78e68137df1..e7b93684ace8 100644 --- a/platform/platform-impl/src/com/intellij/ui/ColorPicker.java +++ b/platform/platform-impl/src/com/intellij/ui/ColorPicker.java @@ -46,6 +46,7 @@ import java.awt.image.ImageObserver; import java.awt.image.MemoryImageSource; import java.text.ParseException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -64,7 +65,7 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen private final JTextField myBlue; private final JTextField myHex; private final Alarm myUpdateQueue; - private final ColorPickerListener[] myExternalListeners; + private final List<ColorPickerListener> myExternalListeners; private final boolean myOpacityInPercent; @@ -88,13 +89,13 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen }; public ColorPicker(@NotNull Disposable parent, @Nullable Color color, boolean enableOpacity) { - this(parent, color, true, enableOpacity, new ColorPickerListener[0], false); + this(parent, color, true, enableOpacity, Collections.<ColorPickerListener>emptyList(), false); } private ColorPicker(Disposable parent, @Nullable Color color, boolean restoreColors, boolean enableOpacity, - ColorPickerListener[] listeners, boolean opacityInPercent) { + List<ColorPickerListener> listeners, boolean opacityInPercent) { myUpdateQueue = new Alarm(Alarm.ThreadToUse.SWING_THREAD, parent); myRed = createColorField(false); myGreen = createColorField(false); @@ -332,7 +333,7 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen String caption, Color preselectedColor, boolean enableOpacity, - ColorPickerListener[] listeners, + List<ColorPickerListener> listeners, boolean opacityInPercent) { final ColorPickerDialog dialog = new ColorPickerDialog(parent, caption, preselectedColor, enableOpacity, listeners, opacityInPercent); dialog.show(); @@ -884,7 +885,7 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen static class ColorPickerDialog extends DialogWrapper { private final Color myPreselectedColor; - private final ColorPickerListener[] myListeners; + private final List<ColorPickerListener> myListeners; private ColorPicker myColorPicker; private final boolean myEnableOpacity; private ColorPipette myPicker; @@ -894,7 +895,7 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen String caption, @Nullable Color preselectedColor, boolean enableOpacity, - ColorPickerListener[] listeners, + List<ColorPickerListener> listeners, boolean opacityInPercent) { super(parent, true); myListeners = listeners; diff --git a/platform/platform-impl/src/com/intellij/ui/ColorPickerListenerFactory.java b/platform/platform-impl/src/com/intellij/ui/ColorPickerListenerFactory.java index 6f1c0479eeca..dbed5e5abb24 100644 --- a/platform/platform-impl/src/com/intellij/ui/ColorPickerListenerFactory.java +++ b/platform/platform-impl/src/com/intellij/ui/ColorPickerListenerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,29 +17,32 @@ package com.intellij.ui; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.psi.PsiElement; -import com.intellij.util.Function; +import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; -/** - * User: ksafonov - */ public abstract class ColorPickerListenerFactory { private static final ExtensionPointName<ColorPickerListenerFactory> EP_NAME = ExtensionPointName.create("com.intellij.colorPickerListenerFactory"); - public static ColorPickerListener[] createListenersFor(@Nullable final PsiElement element) { - final List<ColorPickerListener> listeners = - ContainerUtil.mapNotNull(EP_NAME.getExtensions(), new Function<ColorPickerListenerFactory, ColorPickerListener>() { - @Override - public ColorPickerListener fun(ColorPickerListenerFactory factory) { - return factory.createListener(element); + @NotNull + public static List<ColorPickerListener> createListenersFor(@Nullable PsiElement element) { + List<ColorPickerListener> listeners = null; + for (ColorPickerListenerFactory factory : EP_NAME.getExtensions()) { + ColorPickerListener listener = factory.createListener(element); + if (listener != null) { + if (listeners == null) { + listeners = new SmartList<ColorPickerListener>(); } - }); - return listeners.toArray(new ColorPickerListener[listeners.size()]); + listeners.add(listener); + } + } + return ContainerUtil.notNullize(listeners); } + @Nullable public abstract ColorPickerListener createListener(@Nullable PsiElement element); } diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java b/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java index e803fa5fd63d..d11e990f8dba 100644 --- a/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java +++ b/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java @@ -57,39 +57,39 @@ public abstract class EditorTextFieldCellRenderer implements TableCellRenderer, protected abstract EditorColorsScheme getColorScheme(); - protected abstract String getText(JTable table, Object value, int row, int column); + protected abstract String getText(FontMetrics fontMetrics, JTable table, Object value, int row, int column); protected void customizeEditor(EditorEx editor, Object value, boolean selected, int row, int col) { } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - String text = getText(table, value, row, column); MyPanel panel = getEditorPanel(table); EditorEx editor = panel.editor; int tableFontSize = table.getFont().getSize(); if (editor.getColorsScheme().getEditorFontSize() != tableFontSize) { editor.getColorsScheme().setEditorFontSize(tableFontSize); } - setText(editor, text); - - if (isSelected) { - ((EditorImpl)editor).setPaintSelection(true); - editor.getColorsScheme().setColor(EditorColors.SELECTION_BACKGROUND_COLOR, table.getSelectionBackground()); - editor.getColorsScheme().setColor(EditorColors.SELECTION_FOREGROUND_COLOR, table.getSelectionForeground()); - editor.getSelectionModel().setSelection(0, editor.getDocument().getTextLength()); - editor.setBackgroundColor(table.getSelectionBackground()); - } - else { - ((EditorImpl)editor).setPaintSelection(false); - editor.getSelectionModel().setSelection(0, 0); - boolean selectedRow = table.getSelectedRowCount() > 0 && table.getSelectedRows()[table.getSelectedRowCount() - 1] == row; - editor.setBackgroundColor(!selectedRow ? table.getBackground() : getColorScheme().getColor(EditorColors.CARET_ROW_COLOR)); - } + setText(editor, getText(((EditorImpl)editor).getFontMetrics(Font.PLAIN), table, value, row, column)); + + ((EditorImpl)editor).setPaintSelection(isSelected); + editor.getSelectionModel().setSelection(0, isSelected ? editor.getDocument().getTextLength() : 0); + editor.getColorsScheme().setColor(EditorColors.SELECTION_BACKGROUND_COLOR, table.getSelectionBackground()); + editor.getColorsScheme().setColor(EditorColors.SELECTION_FOREGROUND_COLOR, table.getSelectionForeground()); + editor.setBackgroundColor(getCellBackgroundColor(getColorScheme(), table, isSelected, row)); + + panel.setBorder(null); // prevents double border painting when ExtendedItemRendererComponentWrapper is used + customizeEditor(editor, value, isSelected, row, column); return panel; } + public static Color getCellBackgroundColor(EditorColorsScheme colorsScheme, JTable table, boolean isSelected, int row) { + return isSelected ? table.getSelectionBackground() : + table.getSelectionModel().getLeadSelectionIndex() == row ? colorsScheme.getColor(EditorColors.CARET_ROW_COLOR) : + table.getBackground(); + } + @NotNull private MyPanel getEditorPanel(JTable table) { MyPanel panel = (MyPanel)table.getClientProperty(MY_PANEL_PROPERTY); @@ -142,6 +142,16 @@ public abstract class EditorTextFieldCellRenderer implements TableCellRenderer, } @Override + protected void paintComponent(Graphics g) { + if (getBorder() == null) return; + Color oldColor = g.getColor(); + Rectangle clip = g.getClipBounds(); + g.setColor(editor.getBackgroundColor()); + g.fillRect(clip.x, clip.y, clip.width, clip.height); + g.setColor(oldColor); + } + + @Override public void dispose() { EditorFactory.getInstance().releaseEditor(editor); } diff --git a/platform/platform-impl/src/com/intellij/ui/ShowColorPickerAction.java b/platform/platform-impl/src/com/intellij/ui/ShowColorPickerAction.java index 95f4b7e33861..5327c84c3c8d 100644 --- a/platform/platform-impl/src/com/intellij/ui/ShowColorPickerAction.java +++ b/platform/platform-impl/src/com/intellij/ui/ShowColorPickerAction.java @@ -18,12 +18,12 @@ package com.intellij.ui; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.WindowManager; import javax.swing.*; +import java.util.List; /** * @author Konstantin Bulenkov @@ -34,9 +34,8 @@ public class ShowColorPickerAction extends AnAction { final Project project = e.getProject(); JComponent root = rootComponent(project); if (root != null) { - ColorPickerListener[] listeners = ColorPickerListenerFactory.createListenersFor(e.getData(CommonDataKeys.PSI_ELEMENT)); - final ColorPicker.ColorPickerDialog picker = - new ColorPicker.ColorPickerDialog(root, "Color Picker", null, true, listeners, true); + List<ColorPickerListener> listeners = ColorPickerListenerFactory.createListenersFor(e.getData(CommonDataKeys.PSI_ELEMENT)); + ColorPicker.ColorPickerDialog picker = new ColorPicker.ColorPickerDialog(root, "Color Picker", null, true, listeners, true); picker.setModal(false); picker.show(); } diff --git a/platform/platform-impl/src/com/intellij/ui/Splash.java b/platform/platform-impl/src/com/intellij/ui/Splash.java index 0f4147f61753..023cef7bac06 100644 --- a/platform/platform-impl/src/com/intellij/ui/Splash.java +++ b/platform/platform-impl/src/com/intellij/ui/Splash.java @@ -44,6 +44,7 @@ import java.util.List; */ public class Splash extends JDialog implements StartupProgress { @Nullable public static Rectangle BOUNDS; + private final Icon myImage; private int myProgressHeight = 2; private Color myProgressColor = null; @@ -84,8 +85,16 @@ public class Splash extends JDialog implements StartupProgress { } private void setLocationInTheCenterOfScreen() { - Rectangle deviceBounds = getGraphicsConfiguration().getBounds(); - setLocation((deviceBounds.width - getWidth()) / 2, (deviceBounds.height - getHeight()) / 2); + Rectangle bounds = getGraphicsConfiguration().getBounds(); + if (SystemInfo.isWindows) { + Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration()); + int x = insets.left + (bounds.width - insets.left - insets.right - getWidth()) / 2; + int y = insets.top + (bounds.height - insets.top - insets.bottom - getHeight()) / 2; + setLocation(x, y); + } + else { + setLocation((bounds.width - getWidth()) / 2, (bounds.height - getHeight()) / 2); + } } public Splash(ApplicationInfoEx info) { diff --git a/platform/platform-impl/src/com/intellij/ui/TableExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/TableExpandableItemsHandler.java index af4707c60ec3..b7704a687441 100644 --- a/platform/platform-impl/src/com/intellij/ui/TableExpandableItemsHandler.java +++ b/platform/platform-impl/src/com/intellij/ui/TableExpandableItemsHandler.java @@ -106,22 +106,12 @@ public class TableExpandableItemsHandler extends AbstractExpandableItemsHandler< } public Pair<Component, Rectangle> getCellRendererAndBounds(TableCell key) { - Rectangle cellRect = getCellRect(key); - - int modelColumnIndex = myComponent.convertColumnIndexToModel(key.column); - final int modelRowIndex = myComponent.convertRowIndexToModel(key.row); - TableModel model = myComponent.getModel(); - if (key.row < 0 || key.row >= model.getRowCount() || key.column < 0 || key.column >= model.getColumnCount()) { + if (key.row < 0 || key.row >= myComponent.getRowCount() || key.column < 0 || key.column >= myComponent.getColumnCount()) { return null; } - Component renderer = myComponent - .getCellRenderer(key.row, key.column) - .getTableCellRendererComponent(myComponent, - model.getValueAt(modelRowIndex, modelColumnIndex), - myComponent.getSelectionModel().isSelectedIndex(key.row), - myComponent.hasFocus(), - key.row, key.column); + Rectangle cellRect = getCellRect(key); + Component renderer = myComponent.prepareRenderer(myComponent.getCellRenderer(key.row, key.column), key.row, key.column); cellRect.width = renderer.getPreferredSize().width; return Pair.create(renderer, cellRect); diff --git a/platform/platform-impl/src/com/intellij/ui/TableSpeedSearch.java b/platform/platform-impl/src/com/intellij/ui/TableSpeedSearch.java index 93a9d9390d33..b596204e6ad2 100644 --- a/platform/platform-impl/src/com/intellij/ui/TableSpeedSearch.java +++ b/platform/platform-impl/src/com/intellij/ui/TableSpeedSearch.java @@ -55,7 +55,9 @@ public class TableSpeedSearch extends SpeedSearchBase<JTable> { @Override protected boolean isSpeedSearchEnabled() { - return !getComponent().isEditing() && super.isSpeedSearchEnabled(); + JTable table = getComponent(); + boolean tableIsNotEmpty = table.getRowCount() != 0 && table.getColumnCount() != 0; + return tableIsNotEmpty && !table.isEditing() && super.isSpeedSearchEnabled(); } @Override diff --git a/platform/platform-impl/src/com/intellij/ui/TreeExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/TreeExpandableItemsHandler.java index ad5466267dba..b24e10b943f4 100644 --- a/platform/platform-impl/src/com/intellij/ui/TreeExpandableItemsHandler.java +++ b/platform/platform-impl/src/com/intellij/ui/TreeExpandableItemsHandler.java @@ -148,7 +148,6 @@ public class TreeExpandableItemsHandler extends AbstractExpandableItemsHandler<I @Override protected void doPaintTooltipImage(final Component rComponent, final Rectangle cellBounds, - final int height, final Graphics2D g, Integer key) { final boolean opaque = rComponent.isOpaque(); @@ -169,7 +168,7 @@ public class TreeExpandableItemsHandler extends AbstractExpandableItemsHandler<I rComponent.setBackground(bg); } - super.doPaintTooltipImage(rComponent, cellBounds, height, g, key); + super.doPaintTooltipImage(rComponent, cellBounds, g, key); if (rComponent instanceof JComponent) { ((JComponent)rComponent).setOpaque(opaque); diff --git a/platform/platform-impl/src/com/intellij/ui/messages/JBMacMessages.java b/platform/platform-impl/src/com/intellij/ui/messages/JBMacMessages.java index 6ce0375e75aa..2a70b61c6e8a 100644 --- a/platform/platform-impl/src/com/intellij/ui/messages/JBMacMessages.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/JBMacMessages.java @@ -73,10 +73,14 @@ public class JBMacMessages extends MacMessagesEmulation { Icon icon = errorStyle ? UIUtil.getErrorIcon() : UIUtil.getInformationIcon(); - focusedOptionIndex = (defaultOptionIndex == focusedOptionIndex) ? buttons.length - 1 : focusedOptionIndex; + if (focusedOptionIndex != -1) { + focusedOptionIndex = (defaultOptionIndex == focusedOptionIndex) ? buttons.length - 1 : focusedOptionIndex; + } + + final String defaultOptionTitle = defaultOptionIndex == -1 ? null : buttons[defaultOptionIndex]; + final String focusedButtonTitle = focusedOptionIndex == -1 ? null : buttons[focusedOptionIndex]; - SheetMessage sheetMessage = new SheetMessage(window, title, message, icon, buttons, doNotAskDialogOption, buttons[defaultOptionIndex], - buttons[focusedOptionIndex]); + final SheetMessage sheetMessage = new SheetMessage(window, title, message, icon, buttons, doNotAskDialogOption, defaultOptionTitle, focusedButtonTitle); String result = sheetMessage.getResult(); for (int i = 0; i < buttons.length; i++) { if (result.equals(buttons[i])) { diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java index e1c326d33cd8..78802ccdf6bb 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java @@ -337,7 +337,7 @@ public class AbstractPopup implements JBPopup { } public void setShowHints(boolean show) { - final Window ancestor = SwingUtilities.getWindowAncestor(myComponent); + final Window ancestor = getContentWindow(myComponent); if (ancestor instanceof RootPaneContainer) { final JRootPane rootPane = ((RootPaneContainer)ancestor).getRootPane(); if (rootPane != null) { @@ -757,7 +757,33 @@ public class AbstractPopup implements JBPopup { PopupComponent.Factory factory = getFactory(myForcedHeavyweight || myResizable, forcedDialog); myNativePopup = factory.isNativePopup(); - myPopup = factory.getPopup(myOwner, myContent, targetBounds.x, targetBounds.y, this); + Component popupOwner = myOwner; + if (popupOwner instanceof RootPaneContainer) { + // JDK uses cached heavyweight popup for a window ancestor + RootPaneContainer root = (RootPaneContainer)popupOwner; + popupOwner = root.getRootPane(); + } + if (LOG.isDebugEnabled()) { + LOG.debug("expected preferred size: " + myContent.getPreferredSize()); + } + myPopup = factory.getPopup(popupOwner, myContent, targetBounds.x, targetBounds.y, this); + if (LOG.isDebugEnabled()) { + LOG.debug(" actual preferred size: " + myContent.getPreferredSize()); + } + if ((targetBounds.width != myContent.getWidth()) || (targetBounds.height != myContent.getHeight())) { + // JDK uses cached heavyweight popup that is not initialized properly + LOG.debug("the expected size is not equal to the actual size"); + Window popup = myPopup.getWindow(); + if (popup != null) { + popup.setSize(targetBounds.width, targetBounds.height); + if (myContent.getParent().getComponentCount() != 1) { + LOG.debug("unexpected count of components in heavy-weight popup"); + } + } + else { + LOG.debug("cannot fix size for non-heavy-weight popup"); + } + } if (myResizable) { final JRootPane root = myContent.getRootPane(); @@ -799,13 +825,10 @@ public class AbstractPopup implements JBPopup { listener.beforeShown(new LightweightWindowEvent(this)); } - // can be improved by moving in myPopup code - myPopup.getWindow().setSize(myContent.getSize()); - myPopup.setRequestFocus(myRequestFocus); myPopup.show(); - final Window window = SwingUtilities.getWindowAncestor(myContent); + final Window window = getContentWindow(myContent); myWindow = window; @@ -1185,14 +1208,17 @@ public class AbstractPopup implements JBPopup { size = computeWindowSize(size); - final Window window = SwingUtilities.getWindowAncestor(myContent); - window.setSize(size); + final Window window = getContentWindow(myContent); + if (window != null) { + window.setSize(size); + } } public void pack() { - final Window window = SwingUtilities.getWindowAncestor(myContent); - - window.pack(); + final Window window = getContentWindow(myContent); + if (window != null) { + window.pack(); + } } public JComponent getComponent() { @@ -1211,6 +1237,10 @@ public class AbstractPopup implements JBPopup { } myDisposed = true; + if (LOG.isDebugEnabled()) { + LOG.debug("start disposing " + myContent); + } + Disposer.dispose(this, false); ApplicationManager.getApplication().assertIsDispatchThread(); @@ -1257,6 +1287,10 @@ public class AbstractPopup implements JBPopup { IdeFocusManager.getInstance(myProject).typeAheadUntil(typeAheadDone); getFocusManager().doWhenFocusSettlesDown(runFinal); } + + if (LOG.isDebugEnabled()) { + LOG.debug("stop disposing content"); + } } private void resetWindow() { @@ -1385,15 +1419,27 @@ public class AbstractPopup implements JBPopup { } public static Window moveTo(JComponent content, Point screenPoint, final Dimension headerCorrectionSize) { - setDefaultCursor(content); - final Window wnd = SwingUtilities.getWindowAncestor(content); - if (headerCorrectionSize != null) { - screenPoint.y -= headerCorrectionSize.height; + final Window wnd = getContentWindow(content); + if (wnd != null) { + wnd.setCursor(Cursor.getDefaultCursor()); + if (headerCorrectionSize != null) { + screenPoint.y -= headerCorrectionSize.height; + } + wnd.setLocation(screenPoint); } - wnd.setLocation(screenPoint); return wnd; } + private static Window getContentWindow(Component content) { + Window window = SwingUtilities.getWindowAncestor(content); + if (window == null) { + if (LOG.isDebugEnabled()) { + LOG.debug("no window ancestor for " + content); + } + } + return window; + } + @Override public Point getLocationOnScreen() { Dimension headerCorrectionSize = myLocateByContent ? myHeaderPanel.getPreferredSize() : null; @@ -1467,7 +1513,7 @@ public class AbstractPopup implements JBPopup { } public static void setDefaultCursor(JComponent content) { - final Window wnd = SwingUtilities.getWindowAncestor(content); + final Window wnd = getContentWindow(content); if (wnd != null) { wnd.setCursor(Cursor.getDefaultCursor()); } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java index c7194ca5b4c4..2d7a8e3fb276 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java @@ -227,8 +227,11 @@ public class PopupFactoryImpl extends JBPopupFactory { Presentation presentation = new Presentation(); presentation.setDescription(action.getTemplatePresentation().getDescription()); final String actualActionPlace = actionPlace == null ? ActionPlaces.UNKNOWN : actionPlace; - action.update(new AnActionEvent(null, DataManager.getInstance().getDataContext(myComponent), actualActionPlace, presentation, - ActionManager.getInstance(), 0)); + final AnActionEvent actionEvent = + new AnActionEvent(null, DataManager.getInstance().getDataContext(myComponent), actualActionPlace, presentation, + ActionManager.getInstance(), 0); + actionEvent.setInjectedContext(action.isInInjectedContext()); + action.update(actionEvent); ActionMenu.showDescriptionInStatusBar(true, myComponent, presentation.getDescription()); } }); @@ -730,7 +733,10 @@ public class PopupFactoryImpl extends JBPopupFactory { myFinalRunnable = new Runnable() { @Override public void run() { - action.actionPerformed(new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, action.getTemplatePresentation().clone(), ActionManager.getInstance(), eventModifiers)); + final AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, action.getTemplatePresentation().clone(), + ActionManager.getInstance(), eventModifiers); + event.setInjectedContext(action.isInInjectedContext()); + action.actionPerformed(event); } }; return FINAL_CHOICE; @@ -879,7 +885,10 @@ public class PopupFactoryImpl extends JBPopupFactory { @NotNull private AnActionEvent createActionEvent(@NotNull AnAction actionGroup) { - return new AnActionEvent(null, myDataContext, myActionPlace, getPresentation(actionGroup), ActionManager.getInstance(), 0); + final AnActionEvent actionEvent = + new AnActionEvent(null, myDataContext, myActionPlace, getPresentation(actionGroup), ActionManager.getInstance(), 0); + actionEvent.setInjectedContext(actionGroup.isInInjectedContext()); + return actionEvent; } private void appendActionsFromGroup(@NotNull ActionGroup actionGroup) { diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java b/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java index 72f2e1dc3b37..9383f5c3f08e 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java @@ -18,9 +18,7 @@ package com.intellij.ui.popup.list; import com.intellij.openapi.ui.popup.ListItemDescriptor; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.ui.EngravedLabel; import com.intellij.ui.ErrorLabel; -import com.intellij.ui.Gray; import com.intellij.ui.GroupedElementsRenderer; import com.intellij.ui.components.panels.OpaquePanel; @@ -58,15 +56,8 @@ public class GroupedItemsListRenderer extends GroupedElementsRenderer.List imple @Override protected JComponent createItemComponent() { - if (Registry.is("ide.new.project.settings")) { - myTextLabel = new EngravedLabel(); - myTextLabel.setFont(myTextLabel.getFont().deriveFont(Font.BOLD)); - myTextLabel.setForeground(Gray._240); - } else { - myTextLabel = new ErrorLabel(); - myTextLabel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); - } - + myTextLabel = new ErrorLabel(); + myTextLabel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); myTextLabel.setOpaque(true); return layoutComponent(myTextLabel); } diff --git a/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java b/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java new file mode 100644 index 000000000000..ac4c1b12373c --- /dev/null +++ b/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java @@ -0,0 +1,465 @@ +package com.intellij.util.ui; + +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserFactory; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComponentWithBrowseButton; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.TextComponentAccessor; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.HyperlinkLabel; +import com.intellij.ui.TextFieldWithHistory; +import com.intellij.ui.TextFieldWithHistoryWithBrowseButton; +import com.intellij.util.NotNullProducer; +import com.intellij.util.PlatformIcons; +import com.intellij.util.containers.ComparatorUtil; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import java.awt.*; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +public class SwingHelper { + + private static final Logger LOG = Logger.getInstance(SwingHelper.class); + + /** + * Creates panel whose content consists of given {@code children} components + * stacked vertically each on another in a given order. + * + * @param childAlignmentX Component.LEFT_ALIGNMENT, Component.CENTER_ALIGNMENT or Component.RIGHT_ALIGNMENT + * @param children children components + * @return created panel + */ + @NotNull + public static JPanel newVerticalPanel(float childAlignmentX, Component... children) { + return newGenericBoxPanel(true, childAlignmentX, children); + } + + @NotNull + public static JPanel newLeftAlignedVerticalPanel(Component... children) { + return newVerticalPanel(Component.LEFT_ALIGNMENT, children); + } + + @NotNull + public static JPanel newLeftAlignedVerticalPanel(@NotNull Collection<Component> children) { + return newVerticalPanel(Component.LEFT_ALIGNMENT, children); + } + + @NotNull + public static JPanel newVerticalPanel(float childAlignmentX, @NotNull Collection<Component> children) { + return newVerticalPanel(childAlignmentX, children.toArray(new Component[children.size()])); + } + + /** + * Creates panel whose content consists of given {@code children} components horizontally + * stacked each on another in a given order. + * + * @param childAlignmentY Component.TOP_ALIGNMENT, Component.CENTER_ALIGNMENT or Component.BOTTOM_ALIGNMENT + * @param children children components + * @return created panel + */ + @NotNull + public static JPanel newHorizontalPanel(float childAlignmentY, Component... children) { + return newGenericBoxPanel(false, childAlignmentY, children); + } + + @NotNull + public static JPanel newHorizontalPanel(float childAlignmentY, @NotNull Collection<Component> children) { + return newHorizontalPanel(childAlignmentY, children.toArray(new Component[children.size()])); + } + + private static JPanel newGenericBoxPanel(boolean verticalOrientation, + float childAlignment, + Component... children) { + JPanel panel = new JPanel(); + int axis = verticalOrientation ? BoxLayout.Y_AXIS : BoxLayout.X_AXIS; + panel.setLayout(new BoxLayout(panel, axis)); + for (Component child : children) { + panel.add(child, childAlignment); + if (child instanceof JComponent) { + JComponent jChild = (JComponent) child; + if (verticalOrientation) { + jChild.setAlignmentX(childAlignment); + } else { + jChild.setAlignmentY(childAlignment); + } + } + } + return panel; + } + + @NotNull + public static JPanel wrapWithoutStretch(@NotNull JComponent component) { + JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + panel.add(component); + return panel; + } + + @NotNull + public static JPanel wrapWithHorizontalStretch(@NotNull JComponent component) { + JPanel panel = new JPanel(new BorderLayout(0, 0)); + panel.add(component, BorderLayout.NORTH); + return panel; + } + + public static void setPreferredWidthToFitText(@NotNull TextFieldWithHistoryWithBrowseButton component) { + int childWidth = calcWidthToFitText(component.getChildComponent().getTextEditor(), 35); + setPreferredWidthForComponentWithBrowseButton(component, childWidth); + } + + public static void setPreferredWidthToFitText(@NotNull TextFieldWithBrowseButton component) { + int childWidth = calcWidthToFitText(component.getChildComponent(), 20); + setPreferredWidthForComponentWithBrowseButton(component, childWidth); + } + + private static <T extends JComponent> void setPreferredWidthForComponentWithBrowseButton(@NotNull ComponentWithBrowseButton<T> component, + int childPrefWidth) { + Dimension buttonPrefSize = component.getButton().getPreferredSize(); + setPreferredWidth(component, childPrefWidth + buttonPrefSize.width); + } + + public static void setPreferredWidthToFitText(@NotNull JTextField textField) { + setPreferredWidthToFitText(textField, 15); + } + + public static void setPreferredWidthToFitText(@NotNull JTextField textField, int additionalWidth) { + setPreferredSizeToFitText(textField, StringUtil.notNullize(textField.getText()), additionalWidth); + } + + public static void setPreferredWidthToFitText(@NotNull JTextField textField, @NotNull String text) { + setPreferredSizeToFitText(textField, text, 15); + } + + private static void setPreferredSizeToFitText(@NotNull JTextField textField, @NotNull String text, int additionalWidth) { + int width = calcWidthToFitText(textField, text, additionalWidth); + setPreferredWidth(textField, width); + } + + private static int calcWidthToFitText(@NotNull JTextField textField, int additionalWidth) { + return calcWidthToFitText(textField, textField.getText(), additionalWidth); + } + + private static int calcWidthToFitText(@NotNull JTextField textField, @NotNull String text, int additionalWidth) { + return textField.getFontMetrics(textField.getFont()).stringWidth(text) + additionalWidth; + } + + public static void adjustDialogSizeToFitPreferredSize(@NotNull DialogWrapper dialogWrapper) { + JRootPane rootPane = dialogWrapper.getRootPane(); + Dimension componentSize = rootPane.getSize(); + Dimension componentPreferredSize = rootPane.getPreferredSize(); + if (componentPreferredSize.width <= componentSize.width && componentPreferredSize.height <= componentSize.height) { + return; + } + int dw = Math.max(0, componentPreferredSize.width - componentSize.width); + int dh = Math.max(0, componentPreferredSize.height - componentSize.height); + + Dimension oldDialogSize = dialogWrapper.getSize(); + Dimension newDialogSize = new Dimension(oldDialogSize.width + dw, oldDialogSize.height + dh); + + dialogWrapper.setSize(newDialogSize.width, newDialogSize.height); + rootPane.revalidate(); + rootPane.repaint(); + + LOG.info("DialogWrapper '" + dialogWrapper.getTitle() + "' has been resized (added width: " + dw + ", added height: " + dh + ")"); + } + + public static <T> void updateItems(@NotNull JComboBox comboBox, + @NotNull List<T> newItems, + @Nullable T newSelectedItemIfSelectionCannotBePreserved) { + if (!shouldUpdate(comboBox, newItems)) { + return; + } + Object selectedItem = comboBox.getSelectedItem(); + //noinspection SuspiciousMethodCalls + if (selectedItem != null && !newItems.contains(selectedItem)) { + selectedItem = null; + } + if (selectedItem == null && newItems.contains(newSelectedItemIfSelectionCannotBePreserved)) { + selectedItem = newSelectedItemIfSelectionCannotBePreserved; + } + comboBox.removeAllItems(); + for (T newItem : newItems) { + comboBox.addItem(newItem); + } + if (selectedItem != null) { + int count = comboBox.getItemCount(); + for (int i = 0; i < count; i++) { + Object item = comboBox.getItemAt(i); + if (selectedItem.equals(item)) { + comboBox.setSelectedIndex(i); + break; + } + } + } + } + + private static <T> boolean shouldUpdate(@NotNull JComboBox comboBox, @NotNull List<T> newItems) { + int count = comboBox.getItemCount(); + if (newItems.size() != count) { + return true; + } + for (int i = 0; i < count; i++) { + Object oldItem = comboBox.getItemAt(i); + T newItem = newItems.get(i); + if (!ComparatorUtil.equalsNullable(oldItem, newItem)) { + return true; + } + } + return false; + } + + public static void setNoBorderCellRendererFor(@NotNull TableColumn column) { + final TableCellRenderer previous = column.getCellRenderer(); + column.setCellRenderer(new DefaultTableCellRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + Component component; + if (previous != null) { + component = previous.getTableCellRendererComponent(table, value, isSelected, false, row, column); + } + else { + component = super.getTableCellRendererComponent(table, value, isSelected, false, row, column); + } + if (component instanceof JComponent) { + ((JComponent)component).setBorder(null); + } + return component; + } + }); + } + + public static void addHistoryOnExpansion(@NotNull final TextFieldWithHistory textFieldWithHistory, + @NotNull final NotNullProducer<List<String>> historyProvider) { + textFieldWithHistory.addPopupMenuListener(new PopupMenuListener() { + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + List<String> newHistory = historyProvider.produce(); + Set<String> newHistorySet = ContainerUtil.newHashSet(newHistory); + List<String> oldHistory = textFieldWithHistory.getHistory(); + List<String> mergedHistory = ContainerUtil.newArrayList(); + for (String item : oldHistory) { + if (!newHistorySet.contains(item)) { + mergedHistory.add(item); + } + } + mergedHistory.addAll(newHistory); + textFieldWithHistory.setHistory(mergedHistory); + + setLongestAsPrototype(textFieldWithHistory, mergedHistory); + + // one-time initialization + textFieldWithHistory.removePopupMenuListener(this); + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + } + }); + } + + private static void setLongestAsPrototype(@NotNull JComboBox comboBox, @NotNull List<String> variants) { + Object prototypeDisplayValue = comboBox.getPrototypeDisplayValue(); + String prototypeDisplayValueStr = null; + if (prototypeDisplayValue instanceof String) { + prototypeDisplayValueStr = (String) prototypeDisplayValue; + } + else if (prototypeDisplayValue != null) { + return; + } + String longest = StringUtil.notNullize(prototypeDisplayValueStr); + boolean updated = false; + for (String s : variants) { + if (longest.length() < s.length()) { + longest = s; + updated = true; + } + } + if (updated) { + comboBox.setPrototypeDisplayValue(longest); + } + } + + public static void installFileCompletionAndBrowseDialog(@Nullable Project project, + @NotNull TextFieldWithHistoryWithBrowseButton textFieldWithHistoryWithBrowseButton, + @NotNull String browseDialogTitle, + @NotNull FileChooserDescriptor fileChooserDescriptor) { + doInstall(project, + textFieldWithHistoryWithBrowseButton, + textFieldWithHistoryWithBrowseButton.getChildComponent().getTextEditor(), + browseDialogTitle, + fileChooserDescriptor, + TextComponentAccessor.TEXT_FIELD_WITH_HISTORY_WHOLE_TEXT); + } + + public static void installFileCompletionAndBrowseDialog(@Nullable Project project, + @NotNull TextFieldWithBrowseButton textFieldWithBrowseButton, + @NotNull String browseDialogTitle, + @NotNull FileChooserDescriptor fileChooserDescriptor) { + doInstall(project, + textFieldWithBrowseButton, + textFieldWithBrowseButton.getTextField(), + browseDialogTitle, + fileChooserDescriptor, + TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT); + } + + private static <T extends JComponent> void doInstall(@Nullable Project project, + @NotNull ComponentWithBrowseButton<T> componentWithBrowseButton, + @NotNull JTextField textField, + @NotNull String browseDialogTitle, + @NotNull FileChooserDescriptor fileChooserDescriptor, + @NotNull TextComponentAccessor<T> textComponentAccessor) { + fileChooserDescriptor = fileChooserDescriptor.withShowHiddenFiles(SystemInfo.isUnix); + componentWithBrowseButton.addBrowseFolderListener( + project, + new ComponentWithBrowseButton.BrowseFolderActionListener<T>( + browseDialogTitle, + null, + componentWithBrowseButton, + project, + fileChooserDescriptor, + textComponentAccessor + ), + true + ); + FileChooserFactory.getInstance().installFileCompletion( + textField, + fileChooserDescriptor, + true, + project + ); + } + + @NotNull + public static HyperlinkLabel createWebHyperlink(@NotNull String url) { + return createWebHyperlink(url, url); + } + + @NotNull + public static HyperlinkLabel createWebHyperlink(@NotNull String text, @NotNull String url) { + HyperlinkLabel hyperlink = new HyperlinkLabel(text); + hyperlink.setHyperlinkTarget(url); + + DefaultActionGroup actionGroup = new DefaultActionGroup(); + actionGroup.add(new OpenLinkInBrowser(url)); + actionGroup.add(new CopyLinkAction(url)); + + hyperlink.setComponentPopupMenu(ActionManager.getInstance().createActionPopupMenu("web hyperlink", actionGroup).getComponent()); + return hyperlink; + } + + public static void setPreferredWidth(@NotNull JComponent component, int width) { + Dimension preferredSize = component.getPreferredSize(); + preferredSize.width = width; + component.setPreferredSize(preferredSize); + } + + @NotNull + public static JEditorPane createHtmlViewer(boolean carryTextOver, + @Nullable Font font, + @Nullable Color background, + @Nullable Color foreground) { + final JEditorPane textPane; + if (carryTextOver) { + textPane = new JEditorPane() { + @Override + public Dimension getPreferredSize() { + // This trick makes text component to carry text over to the next line + // if the text line width exceeds parent's width + Dimension dimension = super.getPreferredSize(); + dimension.width = 0; + return dimension; + } + }; + } + else { + textPane = new JEditorPane(); + } + textPane.setFont(font != null ? font : UIUtil.getLabelFont()); + textPane.setContentType(UIUtil.HTML_MIME); + textPane.setEditable(false); + textPane.setBackground(background != null ? background : UIUtil.getLabelBackground()); + textPane.setForeground(foreground != null ? foreground : UIUtil.getLabelForeground()); + return textPane; + } + + public static void setHtml(@NotNull JEditorPane editorPane, @NotNull String bodyInnerHtml) { + String html = String.format( + "<html><head>%s</head><body>%s</body></html>", + UIUtil.getCssFontDeclaration(editorPane.getFont(), null, null, null), + bodyInnerHtml + ); + editorPane.setText(html); + } + + private static class CopyLinkAction extends AnAction { + + private final String myUrl; + + private CopyLinkAction(@NotNull String url) { + super("Copy Link Address", null, PlatformIcons.COPY_ICON); + myUrl = url; + } + + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(true); + } + + @Override + public void actionPerformed(AnActionEvent e) { + Transferable content = new StringSelection(myUrl); + CopyPasteManager.getInstance().setContents(content); + } + } + + private static class OpenLinkInBrowser extends AnAction { + + private final String myUrl; + + private OpenLinkInBrowser(@NotNull String url) { + super("Open Link in Browser", null, PlatformIcons.WEB_ICON); + myUrl = url; + } + + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(true); + } + + @Override + public void actionPerformed(AnActionEvent e) { + BrowserUtil.browse(myUrl); + } + } +}
\ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/util/ui/table/TableModelEditor.java b/platform/platform-impl/src/com/intellij/util/ui/table/TableModelEditor.java index dd41a33a9d15..8b148a3d791d 100644 --- a/platform/platform-impl/src/com/intellij/util/ui/table/TableModelEditor.java +++ b/platform/platform-impl/src/com/intellij/util/ui/table/TableModelEditor.java @@ -22,6 +22,7 @@ import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.*; +import com.intellij.ui.table.JBTable; import com.intellij.ui.table.TableView; import com.intellij.util.Function; import com.intellij.util.FunctionUtil; @@ -42,6 +43,7 @@ import javax.swing.*; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.TableModel; +import java.awt.*; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Collections; @@ -71,6 +73,8 @@ public class TableModelEditor<T> implements ElementProducer<T> { table = new TableView<T>(model); table.setDefaultEditor(Enum.class, ComboBoxTableCellEditor.INSTANCE); table.setStriped(true); + table.setEnableAntialiasing(true); + preferredScrollableViewportHeightInRows(JBTable.PREFERRED_SCROLLABLE_VIEWPORT_HEIGHT_IN_ROWS); new TableSpeedSearch(table); if (columns[0].getColumnClass() == Boolean.class && columns[0].getName().isEmpty()) { TableUtil.setupCheckboxColumn(table.getColumnModel().getColumn(0)); @@ -97,6 +101,11 @@ public class TableModelEditor<T> implements ElementProducer<T> { } } + public TableModelEditor<T> preferredScrollableViewportHeightInRows(int rows) { + table.setPreferredScrollableViewportSize(new Dimension(200, table.getRowHeight() * rows)); + return this; + } + private void addDialogActions() { toolbarDecorator.setEditAction(new AnActionButtonRunnable() { @Override |