001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.ui.editors; 029 030import org.opencms.file.CmsResource; 031import org.opencms.file.types.CmsResourceTypeBinary; 032import org.opencms.file.types.CmsResourceTypeImage; 033import org.opencms.file.types.CmsResourceTypeJsp; 034import org.opencms.file.types.CmsResourceTypeXmlContent; 035import org.opencms.file.types.CmsResourceTypeXmlPage; 036import org.opencms.file.types.I_CmsResourceType; 037import org.opencms.i18n.CmsMessages; 038import org.opencms.json.JSONException; 039import org.opencms.json.JSONObject; 040import org.opencms.lock.CmsLockUtil.LockedFile; 041import org.opencms.main.OpenCms; 042import org.opencms.ui.A_CmsUI; 043import org.opencms.ui.CmsVaadinUtils; 044import org.opencms.ui.FontOpenCms; 045import org.opencms.ui.apps.CmsAppWorkplaceUi; 046import org.opencms.ui.apps.CmsEditor; 047import org.opencms.ui.apps.I_CmsAppSettings; 048import org.opencms.ui.apps.I_CmsAppUIContext; 049import org.opencms.ui.apps.I_CmsHasShortcutActions; 050import org.opencms.ui.components.CmsConfirmationDialog; 051import org.opencms.ui.components.CmsErrorDialog; 052import org.opencms.ui.components.CmsToolBar; 053import org.opencms.ui.components.I_CmsWindowCloseListener; 054import org.opencms.ui.components.OpenCmsTheme; 055import org.opencms.ui.components.codemirror.CmsCodeMirror; 056import org.opencms.ui.components.codemirror.CmsCodeMirror.CodeMirrorLanguage; 057 058import java.util.HashMap; 059import java.util.Map; 060 061import com.vaadin.event.Action; 062import com.vaadin.event.ShortcutAction; 063import com.vaadin.navigator.ViewChangeListener; 064import com.vaadin.ui.Button; 065import com.vaadin.ui.Button.ClickEvent; 066import com.vaadin.ui.Button.ClickListener; 067import com.vaadin.ui.UI; 068import com.vaadin.v7.data.Property.ValueChangeEvent; 069import com.vaadin.v7.data.Property.ValueChangeListener; 070import com.vaadin.v7.ui.ComboBox; 071 072/** 073 * The plain text editor.<p> 074 */ 075@SuppressWarnings("deprecation") 076public class CmsSourceEditor 077implements I_CmsEditor, I_CmsWindowCloseListener, ViewChangeListener, I_CmsHasShortcutActions { 078 079 /** 080 * Stores the editor settings.<p> 081 */ 082 public static class EditorSettings implements I_CmsAppSettings { 083 084 /** JSON key constant. */ 085 private static final String BRACKETS = "brackets"; 086 /** JSON key constant. */ 087 private static final String FONTSIZE = "fontsize"; 088 /** JSON key constant. */ 089 private static final String HIGHLIGHTING = "highlighting"; 090 /** JSON key constant. */ 091 private static final String TABS = "tabs"; 092 /** JSON key constant. */ 093 private static final String WRAPPING = "wrapping"; 094 095 /** The auto close brackets flag. */ 096 boolean m_closeBrackets = true; 097 098 /** The font size. */ 099 String m_fontSize = "16px"; 100 101 /** The highlighting flag. */ 102 boolean m_highlighting = true; 103 104 /** The line wrapping flag. */ 105 boolean m_lineWrapping; 106 107 /** The tab visibility flag. */ 108 boolean m_tabsVisible = true; 109 110 /** 111 * @see org.opencms.ui.apps.I_CmsAppSettings#getSettingsString() 112 */ 113 public String getSettingsString() { 114 115 JSONObject json = new JSONObject(); 116 try { 117 json.put(BRACKETS, m_closeBrackets); 118 json.put(HIGHLIGHTING, m_highlighting); 119 json.put(WRAPPING, m_lineWrapping); 120 json.put(FONTSIZE, m_fontSize); 121 json.put(TABS, m_tabsVisible); 122 } catch (JSONException e) { 123 // TODO Auto-generated catch block 124 e.printStackTrace(); 125 } 126 127 return json.toString(); 128 } 129 130 /** 131 * @see org.opencms.ui.apps.I_CmsAppSettings#restoreSettings(java.lang.String) 132 */ 133 public void restoreSettings(String storedSettings) { 134 135 try { 136 JSONObject json = new JSONObject(storedSettings); 137 if (json.has(BRACKETS)) { 138 m_closeBrackets = json.getBoolean(BRACKETS); 139 } 140 if (json.has(HIGHLIGHTING)) { 141 m_highlighting = json.getBoolean(HIGHLIGHTING); 142 } 143 if (json.has(WRAPPING)) { 144 m_lineWrapping = json.getBoolean(WRAPPING); 145 } 146 if (json.has(TABS)) { 147 m_tabsVisible = json.getBoolean(TABS); 148 } 149 if (json.has(FONTSIZE)) { 150 m_fontSize = json.getString(FONTSIZE); 151 } 152 153 } catch (JSONException e) { 154 // LOG.error("Failed to restore file explorer settings from '" + storedSettings + "'", e); 155 } 156 } 157 } 158 159 /** Exit shortcut. */ 160 private static final Action ACTION_EXIT = new ShortcutAction( 161 "Ctrl+Shift+X", 162 ShortcutAction.KeyCode.X, 163 new int[] {ShortcutAction.ModifierKey.CTRL, ShortcutAction.ModifierKey.SHIFT}); 164 165 /** Exit shortcut, (using Apple CMD as modifier). */ 166 private static final Action ACTION_EXIT_CMD = new ShortcutAction( 167 "CMD+Shift+X", 168 ShortcutAction.KeyCode.X, 169 new int[] {ShortcutAction.ModifierKey.META, ShortcutAction.ModifierKey.SHIFT}); 170 171 /** Save shortcut. */ 172 private static final Action ACTION_SAVE = new ShortcutAction( 173 "Ctrl+S", 174 ShortcutAction.KeyCode.S, 175 new int[] {ShortcutAction.ModifierKey.CTRL}); 176 177 /** Save shortcut, (using Apple CMD as modifier). */ 178 private static final Action ACTION_SAVE_CMD = new ShortcutAction( 179 "CMD+S", 180 ShortcutAction.KeyCode.S, 181 new int[] {ShortcutAction.ModifierKey.META}); 182 183 /** Save & Exit shortcut. */ 184 private static final Action ACTION_SAVE_AND_EXIT = new ShortcutAction( 185 "Ctrl+Shift+S", 186 ShortcutAction.KeyCode.S, 187 new int[] {ShortcutAction.ModifierKey.CTRL, ShortcutAction.ModifierKey.SHIFT}); 188 189 /** Save & Exit shortcut, (using Apple CMD as modifier). */ 190 private static final Action ACTION_SAVE_AND_EXIT_CMD = new ShortcutAction( 191 "CMD+Shift+S", 192 ShortcutAction.KeyCode.S, 193 new int[] {ShortcutAction.ModifierKey.META, ShortcutAction.ModifierKey.SHIFT}); 194 195 /** The available font sizes. */ 196 private static final String[] FONT_SIZES = new String[] {"8px", "10px", "12px", "14px", "16px", "18px", "20px"}; 197 198 /** The serial version id. */ 199 private static final long serialVersionUID = 726920483145397926L; 200 201 /** The editor back link. */ 202 String m_backLink; 203 204 /** The code mirror instance. */ 205 CmsCodeMirror m_codeMirror; 206 207 /** The bundle editor shortcuts. */ 208 Map<Action, Runnable> m_shortcutActions; 209 210 /** The content changed flag. */ 211 private boolean m_changed; 212 213 /** The cleared flag. */ 214 private boolean m_cleared; 215 216 /** The exit button. */ 217 private Button m_exit; 218 219 /** The current file. */ 220 private LockedFile m_file; 221 222 /** The save button. */ 223 private Button m_save; 224 225 /** The save and exit button. */ 226 private Button m_saveAndExit; 227 228 /** 229 * Constructor.<p> 230 */ 231 public CmsSourceEditor() { 232 233 m_shortcutActions = new HashMap<Action, Runnable>(); 234 Runnable save = new Runnable() { 235 236 public void run() { 237 238 save(); 239 } 240 }; 241 m_shortcutActions.put(ACTION_SAVE, save); 242 m_shortcutActions.put(ACTION_SAVE_CMD, save); 243 Runnable saveExit = new Runnable() { 244 245 public void run() { 246 247 saveAndExit(); 248 } 249 }; 250 m_shortcutActions.put(ACTION_SAVE_AND_EXIT, saveExit); 251 m_shortcutActions.put(ACTION_SAVE_AND_EXIT_CMD, saveExit); 252 Runnable exit = new Runnable() { 253 254 public void run() { 255 256 exit(); 257 } 258 }; 259 m_shortcutActions.put(ACTION_EXIT, exit); 260 m_shortcutActions.put(ACTION_EXIT_CMD, exit); 261 } 262 263 /** 264 * @see com.vaadin.navigator.ViewChangeListener#afterViewChange(com.vaadin.navigator.ViewChangeListener.ViewChangeEvent) 265 */ 266 public void afterViewChange(ViewChangeEvent event) { 267 268 // nothing to do 269 } 270 271 /** 272 * @see com.vaadin.navigator.ViewChangeListener#beforeViewChange(com.vaadin.navigator.ViewChangeListener.ViewChangeEvent) 273 */ 274 public boolean beforeViewChange(final ViewChangeEvent event) { 275 276 if (m_changed) { 277 CmsConfirmationDialog.show( 278 CmsVaadinUtils.getMessageText(org.opencms.ui.apps.Messages.GUI_EDITOR_CLOSE_CAPTION_0), 279 CmsVaadinUtils.getMessageText(org.opencms.ui.apps.Messages.GUI_EDITOR_CLOSE_TEXT_0), 280 new Runnable() { 281 282 public void run() { 283 284 clear(); 285 event.getNavigator().navigateTo(event.getViewName()); 286 } 287 }); 288 return false; 289 } 290 if (!m_cleared) { 291 clear(); 292 } 293 return true; 294 } 295 296 /** 297 * Returns the syntax highlighting type for the currently edited resource.<p> 298 * 299 * @param resource the resource to edit 300 * 301 * @return the syntax highlighting type 302 */ 303 public CodeMirrorLanguage getHighlightMode(CmsResource resource) { 304 305 if (resource != null) { 306 // determine resource type 307 int type = resource.getTypeId(); 308 if (CmsResourceTypeJsp.isJspTypeId(type)) { 309 // JSP file 310 return CodeMirrorLanguage.JSP; 311 } 312 if (CmsResourceTypeXmlContent.isXmlContent(resource) || CmsResourceTypeXmlPage.isXmlPage(resource)) { 313 // XML content file or XML page file 314 return CodeMirrorLanguage.XML; 315 } 316 // all other files will be matched according to their suffix 317 int dotIndex = resource.getName().lastIndexOf('.'); 318 if (dotIndex != -1) { 319 String suffix = resource.getName().substring(dotIndex + 1).toLowerCase(); 320 for (CodeMirrorLanguage lang : CodeMirrorLanguage.values()) { 321 if (lang.isSupportedFileType(suffix)) { 322 return lang; 323 } 324 } 325 } 326 } 327 // return HTML type as default 328 return CodeMirrorLanguage.HTML; 329 } 330 331 /** 332 * @see org.opencms.ui.editors.I_CmsEditor#getPriority() 333 */ 334 public int getPriority() { 335 336 return 10; 337 } 338 339 /** 340 * @see org.opencms.ui.apps.I_CmsHasShortcutActions#getShortcutActions() 341 */ 342 public Map<Action, Runnable> getShortcutActions() { 343 344 return m_shortcutActions; 345 } 346 347 /** 348 * @see org.opencms.ui.editors.I_CmsEditor#initUI(org.opencms.ui.apps.I_CmsAppUIContext, org.opencms.file.CmsResource, java.lang.String, java.util.Map) 349 */ 350 public void initUI(I_CmsAppUIContext context, CmsResource resource, String backLink, Map<String, String> params) { 351 352 CmsMessages messages = Messages.get().getBundle(UI.getCurrent().getLocale()); 353 context.showInfoArea(false); 354 context.setAppTitle(messages.key(Messages.GUI_SOURCE_EDITOR_TITLE_0)); 355 CmsAppWorkplaceUi.setWindowTitle( 356 CmsVaadinUtils.getMessageText( 357 org.opencms.ui.apps.Messages.GUI_CONTENT_EDITOR_TITLE_2, 358 resource.getName(), 359 CmsResource.getParentFolder(A_CmsUI.getCmsObject().getSitePath(resource)))); 360 m_backLink = backLink; 361 m_codeMirror = new CmsCodeMirror(); 362 m_codeMirror.setSizeFull(); 363 context.setAppContent(m_codeMirror); 364 context.enableDefaultToolbarButtons(false); 365 m_saveAndExit = CmsToolBar.createButton( 366 FontOpenCms.SAVE_EXIT, 367 messages.key(Messages.GUI_BUTTON_SAVE_AND_EXIT_0), 368 true); 369 m_saveAndExit.addClickListener(new ClickListener() { 370 371 private static final long serialVersionUID = 1L; 372 373 public void buttonClick(ClickEvent event) { 374 375 saveAndExit(); 376 } 377 378 }); 379 m_saveAndExit.setEnabled(false); 380 context.addToolbarButton(m_saveAndExit); 381 382 m_save = CmsToolBar.createButton(FontOpenCms.SAVE, messages.key(Messages.GUI_BUTTON_SAVE_0), true); 383 m_save.addClickListener(new ClickListener() { 384 385 private static final long serialVersionUID = 1L; 386 387 public void buttonClick(ClickEvent event) { 388 389 save(); 390 } 391 392 }); 393 m_save.setEnabled(false); 394 context.addToolbarButton(m_save); 395 396 Button undo = CmsToolBar.createButton(FontOpenCms.UNDO, messages.key(Messages.GUI_BUTTON_UNDO_0), true); 397 context.addToolbarButton(undo); 398 399 Button redo = CmsToolBar.createButton(FontOpenCms.REDO, messages.key(Messages.GUI_BUTTON_REDO_0), true); 400 context.addToolbarButton(redo); 401 402 m_codeMirror.registerUndoRedo(undo, redo); 403 404 Button search = CmsToolBar.createButton(FontOpenCms.SEARCH, messages.key(Messages.GUI_BUTTON_SEARCH_0), true); 405 context.addToolbarButton(search); 406 407 Button replace = CmsToolBar.createButton( 408 FontOpenCms.SEARCH_REPLACE, 409 messages.key(Messages.GUI_BUTTON_REPLACE_0), 410 true); 411 context.addToolbarButton(replace); 412 413 m_codeMirror.registerSearchReplace(search, replace); 414 415 EditorSettings settings; 416 try { 417 settings = OpenCms.getWorkplaceAppManager().getAppSettings(A_CmsUI.getCmsObject(), EditorSettings.class); 418 419 } catch (Exception e) { 420 settings = new EditorSettings(); 421 } 422 423 final Button toggleHighlight = CmsToolBar.createButton( 424 FontOpenCms.HIGHLIGHT, 425 messages.key(Messages.GUI_BUTTON_TOGGLE_HIGHLIGHTING_0)); 426 toggleHighlight.addClickListener(new ClickListener() { 427 428 private static final long serialVersionUID = 1L; 429 430 public void buttonClick(ClickEvent event) { 431 432 Button b = event.getButton(); 433 boolean pressed = b.getStyleName().contains(OpenCmsTheme.BUTTON_PRESSED); 434 if (pressed) { 435 b.removeStyleName(OpenCmsTheme.BUTTON_PRESSED); 436 } else { 437 b.addStyleName(OpenCmsTheme.BUTTON_PRESSED); 438 } 439 m_codeMirror.setHighlighting(!pressed); 440 } 441 442 }); 443 if (settings.m_highlighting) { 444 m_codeMirror.setHighlighting(true); 445 toggleHighlight.addStyleName(OpenCmsTheme.BUTTON_PRESSED); 446 } else { 447 m_codeMirror.setHighlighting(false); 448 } 449 context.addToolbarButtonRight(toggleHighlight); 450 451 final Button toggleLineWrap = CmsToolBar.createButton( 452 FontOpenCms.WRAP_LINES, 453 messages.key(Messages.GUI_BUTTON_TOGGLE_LINE_WRAPPING_0)); 454 toggleLineWrap.addClickListener(new ClickListener() { 455 456 private static final long serialVersionUID = 1L; 457 458 public void buttonClick(ClickEvent event) { 459 460 Button b = event.getButton(); 461 boolean pressed = b.getStyleName().contains(OpenCmsTheme.BUTTON_PRESSED); 462 if (pressed) { 463 b.removeStyleName(OpenCmsTheme.BUTTON_PRESSED); 464 } else { 465 b.addStyleName(OpenCmsTheme.BUTTON_PRESSED); 466 } 467 m_codeMirror.setLineWrapping(!pressed); 468 } 469 470 }); 471 if (settings.m_lineWrapping) { 472 m_codeMirror.setLineWrapping(true); 473 toggleLineWrap.addStyleName(OpenCmsTheme.BUTTON_PRESSED); 474 } else { 475 m_codeMirror.setLineWrapping(false); 476 } 477 context.addToolbarButtonRight(toggleLineWrap); 478 479 final Button toggleBrackets = CmsToolBar.createButton( 480 FontOpenCms.BRACKETS, 481 messages.key(Messages.GUI_BUTTON_TOBBLE_BRACKET_AUTOCLOSE_0)); 482 toggleBrackets.addClickListener(new ClickListener() { 483 484 private static final long serialVersionUID = 1L; 485 486 public void buttonClick(ClickEvent event) { 487 488 Button b = event.getButton(); 489 boolean pressed = b.getStyleName().contains(OpenCmsTheme.BUTTON_PRESSED); 490 if (pressed) { 491 b.removeStyleName(OpenCmsTheme.BUTTON_PRESSED); 492 } else { 493 b.addStyleName(OpenCmsTheme.BUTTON_PRESSED); 494 } 495 m_codeMirror.setCloseBrackets(!pressed); 496 } 497 498 }); 499 if (settings.m_closeBrackets) { 500 m_codeMirror.setCloseBrackets(true); 501 toggleBrackets.addStyleName(OpenCmsTheme.BUTTON_PRESSED); 502 } else { 503 m_codeMirror.setCloseBrackets(false); 504 } 505 context.addToolbarButtonRight(toggleBrackets); 506 507 final Button toggleTabs = CmsToolBar.createButton( 508 FontOpenCms.INVISIBLE_CHARS, 509 messages.key(Messages.GUI_BUTTON_TOGGLE_TAB_VISIBILITY_0)); 510 toggleTabs.addClickListener(new ClickListener() { 511 512 private static final long serialVersionUID = 1L; 513 514 public void buttonClick(ClickEvent event) { 515 516 Button b = event.getButton(); 517 boolean pressed = b.getStyleName().contains(OpenCmsTheme.BUTTON_PRESSED); 518 if (pressed) { 519 b.removeStyleName(OpenCmsTheme.BUTTON_PRESSED); 520 } else { 521 b.addStyleName(OpenCmsTheme.BUTTON_PRESSED); 522 } 523 m_codeMirror.setTabsVisible(!pressed); 524 } 525 526 }); 527 if (settings.m_tabsVisible) { 528 m_codeMirror.setTabsVisible(true); 529 toggleTabs.addStyleName(OpenCmsTheme.BUTTON_PRESSED); 530 } else { 531 m_codeMirror.setTabsVisible(false); 532 } 533 context.addToolbarButtonRight(toggleTabs); 534 535 ComboBox modeSelect = new ComboBox(); 536 modeSelect.setWidth("115px"); 537 modeSelect.addStyleName(OpenCmsTheme.TOOLBAR_FIELD); 538 modeSelect.addStyleName(OpenCmsTheme.REQUIRED_BUTTON); 539 modeSelect.setNullSelectionAllowed(false); 540 modeSelect.setImmediate(true); 541 modeSelect.setNewItemsAllowed(false); 542 for (CodeMirrorLanguage lang : CodeMirrorLanguage.values()) { 543 modeSelect.addItem(lang); 544 modeSelect.setItemCaption(lang, lang.name()); 545 } 546 CodeMirrorLanguage lang = getHighlightMode(resource); 547 modeSelect.setValue(lang); 548 m_codeMirror.setLanguage(lang); 549 modeSelect.addValueChangeListener(new ValueChangeListener() { 550 551 private static final long serialVersionUID = 1L; 552 553 public void valueChange(ValueChangeEvent event) { 554 555 m_codeMirror.setLanguage((CodeMirrorLanguage)event.getProperty().getValue()); 556 } 557 }); 558 context.addToolbarButtonRight(modeSelect); 559 560 ComboBox fontSizeSelect = new ComboBox(); 561 fontSizeSelect.setWidth("75px"); 562 fontSizeSelect.addStyleName(OpenCmsTheme.TOOLBAR_FIELD); 563 fontSizeSelect.addStyleName(OpenCmsTheme.REQUIRED_BUTTON); 564 fontSizeSelect.setNullSelectionAllowed(false); 565 fontSizeSelect.setImmediate(true); 566 fontSizeSelect.setNewItemsAllowed(false); 567 for (int i = 0; i < FONT_SIZES.length; i++) { 568 fontSizeSelect.addItem(FONT_SIZES[i]); 569 } 570 fontSizeSelect.setValue(settings.m_fontSize); 571 fontSizeSelect.addValueChangeListener(new ValueChangeListener() { 572 573 private static final long serialVersionUID = 1L; 574 575 public void valueChange(ValueChangeEvent event) { 576 577 m_codeMirror.setFontSize((String)event.getProperty().getValue()); 578 } 579 }); 580 context.addToolbarButtonRight(fontSizeSelect); 581 m_codeMirror.setFontSize(settings.m_fontSize); 582 583 m_exit = CmsToolBar.createButton(FontOpenCms.EXIT, messages.key(Messages.GUI_BUTTON_CANCEL_0), true); 584 m_exit.addClickListener(new ClickListener() { 585 586 private static final long serialVersionUID = 1L; 587 588 public void buttonClick(ClickEvent event) { 589 590 exit(); 591 } 592 593 }); 594 context.addToolbarButtonRight(m_exit); 595 596 try { 597 m_file = LockedFile.lockResource(A_CmsUI.getCmsObject(), resource); 598 String content = new String(m_file.getFile().getContents(), m_file.getEncoding()); 599 m_codeMirror.setValue(content); 600 } catch (Exception e) { 601 CmsErrorDialog.showErrorDialog(e); 602 } 603 m_codeMirror.addValueChangeListener(new ValueChangeListener() { 604 605 private static final long serialVersionUID = 1L; 606 607 public void valueChange(ValueChangeEvent event) { 608 609 onChange((String)event.getProperty().getValue()); 610 } 611 }); 612 } 613 614 /** 615 * @see org.opencms.ui.editors.I_CmsEditor#matchesResource(org.opencms.file.CmsResource, boolean) 616 */ 617 public boolean matchesResource(CmsResource resource, boolean plainText) { 618 619 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(resource); 620 return matchesType(type, plainText); 621 } 622 623 /** 624 * @see org.opencms.ui.editors.I_CmsEditor#matchesType(org.opencms.file.types.I_CmsResourceType, boolean) 625 */ 626 public boolean matchesType(I_CmsResourceType type, boolean plainText) { 627 628 return !((type instanceof CmsResourceTypeBinary) || (type instanceof CmsResourceTypeImage)); 629 } 630 631 /** 632 * @see org.opencms.ui.editors.I_CmsEditor#newInstance() 633 */ 634 public I_CmsEditor newInstance() { 635 636 return new CmsSourceEditor(); 637 } 638 639 /** 640 * @see org.opencms.ui.components.I_CmsWindowCloseListener#onWindowClose() 641 */ 642 public void onWindowClose() { 643 644 clear(); 645 } 646 647 /** 648 * Unlocks the edited file before leaving the editor.<p> 649 */ 650 void clear() { 651 652 m_cleared = true; 653 m_changed = false; 654 m_file.tryUnlock(); 655 OpenCms.getWorkplaceAppManager().storeAppSettings( 656 A_CmsUI.getCmsObject(), 657 EditorSettings.class, 658 getCurrentSettings()); 659 } 660 661 /** 662 * Exits the editor without saving.<p> 663 * Will ask to confirm exit on changed contents.<p> 664 */ 665 void exit() { 666 667 if (m_changed) { 668 CmsConfirmationDialog.show( 669 CmsVaadinUtils.getMessageText(org.opencms.ui.apps.Messages.GUI_EDITOR_CLOSE_CAPTION_0), 670 CmsVaadinUtils.getMessageText(org.opencms.ui.apps.Messages.GUI_EDITOR_CLOSE_TEXT_0), 671 new Runnable() { 672 673 public void run() { 674 675 exitInternal(); 676 } 677 }); 678 } else { 679 exitInternal(); 680 } 681 682 } 683 684 /** 685 * Exits the editor without saving.<p> 686 */ 687 void exitInternal() { 688 689 clear(); 690 CmsEditor.openBackLink(m_backLink); 691 } 692 693 /** 694 * Called on content change.<p> 695 * 696 * @param value the changed content value 697 */ 698 void onChange(String value) { 699 700 m_changed = true; 701 m_save.setEnabled(true); 702 m_saveAndExit.setEnabled(true); 703 } 704 705 /** 706 * Saves the current editor content.<p> 707 */ 708 void save() { 709 710 try { 711 byte[] content = m_codeMirror.getValue().getBytes(m_file.getEncoding()); 712 m_file.getFile().setContents(content); 713 A_CmsUI.getCmsObject().writeFile(m_file.getFile()); 714 m_changed = false; 715 m_save.setEnabled(false); 716 m_saveAndExit.setEnabled(false); 717 } catch (Exception e) { 718 CmsErrorDialog.showErrorDialog(e); 719 } 720 } 721 722 /** 723 * Saves the current editor content and leaves the editor.<p> 724 */ 725 void saveAndExit() { 726 727 save(); 728 exit(); 729 } 730 731 /** 732 * Returns the current editor settings.<p> 733 * 734 * @return the current editor settings 735 */ 736 private EditorSettings getCurrentSettings() { 737 738 EditorSettings result = new EditorSettings(); 739 result.m_closeBrackets = m_codeMirror.isCloseBrackets(); 740 result.m_lineWrapping = m_codeMirror.isLineWrapping(); 741 result.m_highlighting = m_codeMirror.isHighlighting(); 742 result.m_tabsVisible = m_codeMirror.isTabsVisible(); 743 result.m_fontSize = m_codeMirror.getFontSize(); 744 return result; 745 } 746}