1 /* 2 * This file is part of the LibreOffice project. 3 * 4 * This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 * 8 * This file incorporates work covered by the following license notice: 9 * 10 * Licensed to the Apache Software Foundation (ASF) under one or more 11 * contributor license agreements. See the NOTICE file distributed 12 * with this work for additional information regarding copyright 13 * ownership. The ASF licenses this file to you under the Apache 14 * License, Version 2.0 (the "License"); you may not use this file 15 * except in compliance with the License. You may obtain a copy of 16 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 17 */ 18 package com.sun.star.wizards.ui; 19 20 import javax.swing.ListModel; 21 import com.sun.star.awt.ActionEvent; 22 import com.sun.star.awt.Size; 23 import com.sun.star.awt.XActionListener; 24 import com.sun.star.awt.XButton; 25 import com.sun.star.awt.XControl; 26 import com.sun.star.awt.XControlModel; 27 import com.sun.star.awt.XFixedText; 28 import com.sun.star.awt.XItemEventBroadcaster; 29 import com.sun.star.awt.XItemListener; 30 import com.sun.star.awt.XWindow; 31 import com.sun.star.lang.EventObject; 32 import com.sun.star.uno.UnoRuntime; 33 import com.sun.star.wizards.common.HelpIds; 34 import com.sun.star.wizards.common.Helper; 35 import com.sun.star.wizards.common.IRenderer; 36 import com.sun.star.wizards.common.PropertyNames; 37 import com.sun.star.wizards.common.PropertySetHelper; 38 import com.sun.star.wizards.ui.event.XActionListenerAdapter; 39 40 public class ButtonList implements XItemEventBroadcaster, XActionListener 41 { 42 43 private XFixedText lblImageText; 44 private XButton btnBack; 45 private XButton btnNext; 46 private XFixedText lblCounter; 47 private XControl m_aButtons[]; 48 private boolean benabled = true; 49 private UnoDialog2 oUnoDialog; 50 private Size gap = new Size(4, 4); 51 private int cols = 4; 52 private int rows = 3; 53 private Size m_aButtonSize = new Size(20, 20); 54 private Size pos; 55 private boolean showButtons = true; 56 private Short step; 57 private static final boolean refreshOverNull = true; 58 private static final int imageTextLines = 1; 59 private boolean rowSelect = false; 60 public int tabIndex; 61 private String m_aControlName = "il"; 62 private int m_nCurrentSelection = -1; 63 private int pageStart = 0; 64 public int helpURL = 0; 65 private IRenderer renderer; 66 private ListModel listModel; 67 private IRenderer counterRenderer = new SimpleCounterRenderer(); 68 private static final int LINE_HEIGHT = 8; 69 setName(String _sName)70 public void setName(String _sName) 71 { 72 m_aControlName = _sName; 73 } 74 75 /** Setter for property m_aButtonSize. 76 * @param imageSize New value of property m_aButtonSize. 77 */ setButtonSize(Size imageSize)78 public void setButtonSize(Size imageSize) 79 { 80 this.m_aButtonSize = imageSize; 81 } 82 disposing(EventObject arg0)83 public void disposing(EventObject arg0) 84 { 85 } 86 create(UnoDialog2 dialog)87 public void create(UnoDialog2 dialog) 88 { 89 oUnoDialog = dialog; 90 91 int imageTextHeight = imageTextLines * LINE_HEIGHT; 92 93 int nXPos = pos.Width + 1; 94 int nYPos = pos.Height + (m_aButtonSize.Height + gap.Height) * rows + gap.Height; 95 int nWidth = cols * (m_aButtonSize.Width + gap.Width) + gap.Width - 2; 96 97 lblImageText = dialog.insertLabel(m_aControlName + "_imageText", 98 new String[] 99 { 100 PropertyNames.PROPERTY_HEIGHT, 101 PropertyNames.PROPERTY_HELPURL, 102 PropertyNames.PROPERTY_LABEL, 103 PropertyNames.PROPERTY_POSITION_X, 104 PropertyNames.PROPERTY_POSITION_Y, 105 PropertyNames.PROPERTY_STEP, 106 PropertyNames.PROPERTY_TABINDEX, 107 "Tabstop", 108 PropertyNames.PROPERTY_WIDTH 109 }, 110 new Object[] 111 { 112 Integer.valueOf(imageTextHeight), 113 PropertyNames.EMPTY_STRING, 114 "(1)", 115 Integer.valueOf(nXPos), 116 Integer.valueOf(nYPos), 117 step, 118 Short.valueOf((short) 0), 119 Boolean.FALSE, 120 Integer.valueOf(nWidth) 121 }); 122 123 124 if (showButtons) 125 { 126 final String[] pNames1 = new String[] 127 { 128 PropertyNames.PROPERTY_HEIGHT, 129 PropertyNames.PROPERTY_HELPURL, 130 PropertyNames.PROPERTY_POSITION_X, 131 PropertyNames.PROPERTY_POSITION_Y, 132 PropertyNames.PROPERTY_STEP, 133 PropertyNames.PROPERTY_TABINDEX, 134 "Tabstop", 135 PropertyNames.PROPERTY_WIDTH 136 }; 137 138 final Integer btnSize = Integer.valueOf(14); 139 140 // TODO: if list of strings not the same length of list object, office will die. 141 btnBack = dialog.insertButton(m_aControlName + "_btnBack", new XActionListenerAdapter() { 142 @Override 143 public void actionPerformed(ActionEvent event) { 144 prevPage(); 145 } 146 }, pNames1, new Object[] 147 { 148 btnSize, 149 HelpIds.getHelpIdString(helpURL++), 150 Integer.valueOf(pos.Width), 151 Integer.valueOf(pos.Height + (m_aButtonSize.Height + gap.Height) * rows + gap.Height + imageTextHeight + 1), 152 step, 153 Short.valueOf((short) (tabIndex + 1)), 154 Boolean.TRUE, 155 btnSize 156 }); 157 158 btnNext = dialog.insertButton(m_aControlName + "_btnNext", new XActionListenerAdapter() { 159 @Override 160 public void actionPerformed(ActionEvent event) { 161 nextPage(); 162 } 163 }, pNames1, new Object[] 164 { 165 btnSize, 166 HelpIds.getHelpIdString(helpURL++), 167 Integer.valueOf(pos.Width + (m_aButtonSize.Width + gap.Width) * cols + gap.Width - btnSize.intValue() + 1), 168 Integer.valueOf(pos.Height + (m_aButtonSize.Height + gap.Height) * rows + gap.Height + imageTextHeight + 1), 169 step, 170 Short.valueOf((short) (tabIndex + 2)), 171 Boolean.TRUE, 172 btnSize 173 }); 174 175 lblCounter = dialog.insertLabel(m_aControlName + "_lblCounter", pNames1, new Object[] 176 { 177 Integer.valueOf(LINE_HEIGHT), 178 PropertyNames.EMPTY_STRING, 179 Integer.valueOf(pos.Width + btnSize.intValue() + 1), 180 Integer.valueOf(pos.Height + (m_aButtonSize.Height + gap.Height) * rows + gap.Height + imageTextHeight + ((btnSize.intValue() - LINE_HEIGHT) / 2)), 181 step, 182 Short.valueOf((short) 0), 183 Boolean.FALSE, 184 Integer.valueOf(cols * (m_aButtonSize.Width + gap.Width) + gap.Width - 2 * btnSize.intValue() - 1) 185 }); 186 187 Helper.setUnoPropertyValue(getModel(lblCounter), PropertyNames.PROPERTY_ALIGN, Short.valueOf((short) 1)); 188 Helper.setUnoPropertyValue(getModel(btnBack), PropertyNames.PROPERTY_LABEL, "<"); 189 Helper.setUnoPropertyValue(getModel(btnNext), PropertyNames.PROPERTY_LABEL, ">"); 190 191 192 } 193 194 m_tabIndex = Short.valueOf((short) tabIndex); 195 196 m_aButtons = new XControl[rows * cols]; 197 198 m_aButtonHeight = Integer.valueOf(m_aButtonSize.Height); 199 m_aButtonWidth = Integer.valueOf(m_aButtonSize.Width); 200 201 for (int r = 0; r < rows; r++) 202 { 203 for (int c = 0; c < cols; c++) 204 { 205 XButton aButton = createButton(dialog, r, c); 206 XControl aControl = UnoRuntime.queryInterface(XControl.class, aButton); 207 m_aButtons[r * cols + c] = aControl; 208 } 209 } 210 refreshImages(); 211 } 212 213 private Integer m_aButtonHeight; 214 private Integer m_aButtonWidth; 215 private Short m_tabIndex; 216 createButton(UnoDialog2 dialog, int _row, int _col)217 private XButton createButton(UnoDialog2 dialog, int _row, int _col) 218 { 219 String sButtonName = m_aControlName + "_button" + (_row * cols + _col); 220 int nButtonX = getButtonPosX(_col); 221 int nButtonY = getButtonPosY(_row); 222 XButton aButton = dialog.insertImageButton(sButtonName, this, 223 new String[] 224 { 225 /* PropertyNames.PROPERTY_BORDER, */ 226 /* "BackgroundColor", */ 227 PropertyNames.PROPERTY_HEIGHT, 228 PropertyNames.PROPERTY_HELPURL, 229 /* PropertyNames.PROPERTY_LABEL, */ 230 PropertyNames.PROPERTY_POSITION_X, 231 PropertyNames.PROPERTY_POSITION_Y, 232 /* "ScaleImage", */ 233 PropertyNames.PROPERTY_STEP, 234 PropertyNames.PROPERTY_TABINDEX, 235 "Tabstop", 236 "Toggle", 237 PropertyNames.PROPERTY_WIDTH 238 }, 239 new Object[] 240 { 241 /* Short.valueOf((short) 1), */ /* NO_BORDER, */ 242 /* BACKGROUND_COLOR, */ 243 m_aButtonHeight, 244 HelpIds.getHelpIdString(helpURL++), 245 /* "Test", */ 246 Integer.valueOf(nButtonX), 247 Integer.valueOf(nButtonY), 248 /* scaleImages, */ 249 step, 250 m_tabIndex, 251 Boolean.TRUE, 252 Boolean.TRUE, /* Toggle */ 253 m_aButtonWidth 254 }); 255 256 XWindow win = UnoRuntime.queryInterface(XWindow.class, aButton); 257 win.setEnable(true); 258 win.setVisible(true); 259 return aButton; 260 } 261 getButtonPosX(int _col)262 private int getButtonPosX(int _col) 263 { 264 return pos.Width + _col * (m_aButtonSize.Width + gap.Width) + gap.Width; 265 } 266 getButtonPosY(int _row)267 private int getButtonPosY(int _row) 268 { 269 return pos.Height + _row * (m_aButtonSize.Height + gap.Height) + gap.Height; 270 } 271 refreshImages()272 private void refreshImages() 273 { 274 if (showButtons) 275 { 276 refreshCounterText(); 277 } 278 if (refreshOverNull) 279 { 280 for (int i = 0; i < m_aButtons.length; i++) 281 { 282 setVisible(m_aButtons[i], false); 283 } 284 } 285 for (int i = 0; i < m_aButtons.length; i++) 286 { 287 String oResource = getObjectFor(i); 288 if (oResource == null) 289 continue; 290 oUnoDialog.getPeerConfiguration().setImageUrl(m_aButtons[i].getModel(), oResource); 291 boolean bTabStop = Boolean.TRUE; // focusable ? Boolean.TRUE : Boolean.FALSE; 292 Helper.setUnoPropertyValue(m_aButtons[i].getModel(), "Tabstop", bTabStop); 293 if (refreshOverNull) 294 { 295 setVisible(m_aButtons[i], true); 296 } 297 } 298 } 299 refreshCounterText()300 private void refreshCounterText() 301 { 302 Helper.setUnoPropertyValue(getModel(lblCounter), PropertyNames.PROPERTY_LABEL, counterRenderer.render(new Counter(pageStart + 1, pageEnd(), listModel.getSize()))); 303 } 304 pageEnd()305 private int pageEnd() 306 { 307 int i = pageStart + cols * rows; 308 if (i > listModel.getSize() - 1) 309 { 310 return listModel.getSize(); 311 } 312 else 313 { 314 return i; 315 } 316 } 317 318 /** Utility field holding list of ItemListeners. */ 319 private transient java.util.ArrayList<XItemListener> m_aItemListenerList; setVisible(Object control, boolean visible)320 private void setVisible(Object control, boolean visible) 321 { 322 final XWindow xWindow = UnoRuntime.queryInterface(XWindow.class, control); 323 xWindow.setVisible(visible); 324 } 325 326 /** 327 * @param i 328 * @return the String in the list model corresponding to the given image url 329 */ getObjectFor(int i)330 private String getObjectFor(int i) 331 { 332 int ii = getIndexFor(i); 333 if (listModel.getSize() <= ii) 334 { 335 return null; 336 } 337 else 338 { 339 return (String)listModel.getElementAt(ii); 340 } 341 } 342 343 /** 344 * @param i 345 * @return the index in the listModel for the given image index. 346 */ getIndexFor(int i)347 private int getIndexFor(int i) 348 { 349 return pageStart + i; 350 } 351 352 /** Registers ItemListener to receive events. 353 * @param listener The listener to register. 354 */ addItemListener(XItemListener listener)355 public synchronized void addItemListener(XItemListener listener) 356 { 357 if (m_aItemListenerList == null) 358 { 359 m_aItemListenerList = new java.util.ArrayList<XItemListener>(); 360 } 361 m_aItemListenerList.add(listener); 362 } 363 364 /** Removes ItemListener from the list of listeners. 365 * @param listener The listener to remove. 366 */ removeItemListener(XItemListener listener)367 public synchronized void removeItemListener(XItemListener listener) 368 { 369 if (m_aItemListenerList != null) 370 { 371 m_aItemListenerList.remove(listener); 372 } 373 } 374 375 /** Notifies all registered listeners about the event. 376 * 377 */ fireItemSelected()378 private void fireItemSelected() 379 { 380 java.util.ArrayList<XItemListener> list; 381 synchronized(this) 382 { 383 if (m_aItemListenerList == null) 384 { 385 return; 386 } 387 list = (java.util.ArrayList<XItemListener>) m_aItemListenerList.clone(); 388 } 389 for (int i = 0; i < list.size(); i++) 390 { 391 list.get(i).itemStateChanged(null); 392 } 393 } 394 getListModel()395 private ListModel getListModel() 396 { 397 return listModel; 398 } 399 getSelected()400 public int getSelected() 401 { 402 return m_nCurrentSelection; 403 } 404 setCols(int i)405 public void setCols(int i) 406 { 407 cols = i; 408 } 409 setGap(Size size)410 public void setGap(Size size) 411 { 412 gap = size; 413 } 414 setListModel(ListModel model)415 public void setListModel(ListModel model) 416 { 417 listModel = model; 418 } 419 setStep(Short short1)420 public void setStep(Short short1) 421 { 422 step = short1; 423 } 424 setPageStart(int i)425 private void setPageStart(int i) 426 { 427 if (i == pageStart) 428 { 429 return; 430 } 431 pageStart = i; 432 enableButtons(); 433 refreshImages(); 434 } 435 setPos(Size _size)436 public void setPos(Size _size) 437 { 438 pos = _size; 439 } 440 setRenderer(IRenderer _renderer)441 public void setRenderer(IRenderer _renderer) 442 { 443 this.renderer = _renderer; 444 } 445 setRows(int i)446 public void setRows(int i) 447 { 448 rows = i; 449 } 450 setSelected(int i)451 public void setSelected(int i) 452 { 453 if (rowSelect && (i >= 0)) 454 { 455 i = (i / cols) * cols; 456 } 457 if (m_nCurrentSelection == i) 458 { 459 return; 460 } 461 m_nCurrentSelection = i; 462 refreshImageText(); 463 refreshSelection(); 464 fireItemSelected(); 465 } 466 467 /** 468 * set the text under the button list 469 */ refreshImageText()470 private void refreshImageText() 471 { 472 String sText; 473 Object item = m_nCurrentSelection >= 0 ? getListModel().getElementAt(m_nCurrentSelection) : null; 474 if (item != null) { 475 sText = PropertyNames.SPACE + renderer.render(item); 476 } 477 else { 478 sText = ""; 479 } 480 Helper.setUnoPropertyValue(getModel(lblImageText), PropertyNames.PROPERTY_LABEL, sText); 481 } 482 setShowButtons(boolean b)483 public void setShowButtons(boolean b) 484 { 485 showButtons = b; 486 } 487 nextPage()488 private void nextPage() 489 { 490 if (pageStart < getListModel().getSize() - rows * cols) 491 { 492 setPageStart(pageStart + rows * cols); 493 } 494 } 495 prevPage()496 private void prevPage() 497 { 498 if (pageStart == 0) 499 { 500 return; 501 } 502 int i = pageStart - rows * cols; 503 if (i < 0) 504 { 505 i = 0; 506 } 507 setPageStart(i); 508 } 509 enableButtons()510 private void enableButtons() 511 { 512 enable(btnNext, Boolean.valueOf(pageStart + rows * cols < listModel.getSize())); 513 enable(btnBack, Boolean.valueOf(pageStart > 0)); 514 } 515 enable(Object control, Boolean enable)516 private void enable(Object control, Boolean enable) 517 { 518 Helper.setUnoPropertyValue(getModel(control), PropertyNames.PROPERTY_ENABLED, enable); 519 } 520 getModel(Object control)521 private Object getModel(Object control) 522 { 523 return UnoRuntime.queryInterface(XControl.class, control).getModel(); 524 } 525 526 private static class SimpleCounterRenderer implements IRenderer 527 { 528 render(Object counter)529 public String render(Object counter) 530 { 531 return PropertyNames.EMPTY_STRING + ((Counter) counter).start + ".." + ((Counter) counter).end + "/" + ((Counter) counter).max; 532 } 533 } 534 535 private static class Counter 536 { 537 538 private int start, end, max; 539 Counter(int start_, int end_, int max_)540 private Counter(int start_, int end_, int max_) 541 { 542 start = start_; 543 end = end_; 544 max = max_; 545 } 546 } 547 isenabled()548 public boolean isenabled() 549 { 550 return benabled; 551 } 552 setenabled(boolean b)553 public void setenabled(boolean b) 554 { 555 556 for (int i = 0; i < m_aButtons.length; i++) 557 { 558 UnoDialog2.setEnabled(m_aButtons[i], b); 559 } 560 UnoDialog2.setEnabled(lblImageText, b); 561 if (showButtons) 562 { 563 UnoDialog2.setEnabled(btnBack, b); 564 UnoDialog2.setEnabled(btnNext, b); 565 UnoDialog2.setEnabled(lblCounter, b); 566 } 567 benabled = b; 568 } 569 570 /** 571 * refresh on all buttons, the selected button will get state pressed 572 */ refreshSelection()573 private void refreshSelection() 574 { 575 // reset all buttons to not set 576 for (int i = 0; i < m_aButtons.length; i++) 577 { 578 if (m_aButtons[i] != null) 579 { 580 XControlModel xModel = (XControlModel)UnoDialog2.getModel(m_aButtons[i]); 581 PropertySetHelper aHelper = new PropertySetHelper(xModel); 582 if (i == m_nCurrentSelection) 583 { 584 final short one = 1; 585 aHelper.setPropertyValueDontThrow(PropertyNames.PROPERTY_STATE, Short.valueOf(one)); 586 } 587 else 588 { 589 final short zero = 0; 590 aHelper.setPropertyValueDontThrow(PropertyNames.PROPERTY_STATE, Short.valueOf(zero)); 591 } 592 } 593 } 594 } 595 596 /** 597 * implementation of XActionListener 598 * will call if a button from the m_aButtonList is pressed. 599 */ actionPerformed(com.sun.star.awt.ActionEvent actionEvent)600 public void actionPerformed(com.sun.star.awt.ActionEvent actionEvent) 601 { 602 XControlModel xModel = (XControlModel)UnoDialog2.getModel(actionEvent.Source); 603 PropertySetHelper aHelper = new PropertySetHelper(xModel); 604 605 int nState = aHelper.getPropertyValueAsInteger(PropertyNames.PROPERTY_STATE, -1); 606 if (nState == 0) 607 { 608 // this will avoid a wrong state, if already pressed. 609 aHelper.setPropertyValueDontThrow(PropertyNames.PROPERTY_STATE, Short.valueOf((short)1)); 610 } 611 612 // check which Button is pressed. 613 String sControlName = aHelper.getPropertyValueAsString(PropertyNames.PROPERTY_NAME, PropertyNames.EMPTY_STRING); 614 final String sButton = sControlName.substring(7 + m_aControlName.length()); 615 int nButton = Integer.parseInt(sButton); 616 617 int index = getIndexFor(nButton); 618 if (index < listModel.getSize()) 619 { 620 setSelected(index); 621 } 622 623 } 624 625 626 } 627