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