Commit e45b0746 authored by Michael Büsch's avatar Michael Büsch

gui: Add find/replace dialog

Signed-off-by: Michael Büsch's avatarMichael Buesch <m@bues.ch>
parent 977fd6c1
......@@ -4,5 +4,4 @@ S7 compatibility:
- Implement parsing of attributes
GUI:
- Add editor 'find'
- Save window status (open MDI windows, positions, etc)
# -*- coding: utf-8 -*-
#
# Find and replace dialog
#
# Copyright 2015 Michael Buesch <m@bues.ch>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
from __future__ import division, absolute_import, print_function, unicode_literals
from awlsim.common.compat import *
from awlsim.gui.util import *
class FindReplaceDialog(QDialog):
"""Text find and replace dialog."""
def __init__(self, textEdit, withReplace=True, parent=None):
QDialog.__init__(self, parent)
self.setWindowTitle("Find and replace text")
self.setLayout(QGridLayout())
label = QLabel("Find:", self)
self.layout().addWidget(label, 0, 0)
self.findText = QLineEdit(self)
self.layout().addWidget(self.findText, 0, 1)
self.regEx = QCheckBox("Regular &expression", self)
self.layout().addWidget(self.regEx, 1, 1)
if withReplace:
label = QLabel("Replace with:", self)
self.layout().addWidget(label, 2, 0)
self.replaceText = QLineEdit(self)
self.layout().addWidget(self.replaceText, 2, 1)
optsLayout = QHBoxLayout()
group = QGroupBox(self)
group.setLayout(QVBoxLayout())
self.fromCursor = QCheckBox("From &cursor", self)
self.fromCursor.setCheckState(Qt.Checked)
group.layout().addWidget(self.fromCursor)
self.dirUp = QRadioButton("&Up", self)
group.layout().addWidget(self.dirUp)
self.dirDown = QRadioButton("&Down", self)
self.dirDown.setChecked(True)
group.layout().addWidget(self.dirDown)
group.layout().addStretch()
optsLayout.addWidget(group)
group = QGroupBox(self)
group.setLayout(QVBoxLayout())
self.caseSensitive = QCheckBox("Case &sensitive", self)
group.layout().addWidget(self.caseSensitive)
self.wholeWords = QCheckBox("&Whole words only", self)
group.layout().addWidget(self.wholeWords)
group.layout().addStretch()
optsLayout.addWidget(group)
self.layout().addLayout(optsLayout, 3, 0, 1, 2)
self.statusLabel = QLabel(self)
self.layout().addWidget(self.statusLabel, 4, 0, 1, 3)
buttonsLayout = QVBoxLayout()
self.findButton = QPushButton(self)
buttonsLayout.addWidget(self.findButton)
if withReplace:
self.replaceButton = QPushButton("&Replace", self)
buttonsLayout.addWidget(self.replaceButton)
self.replaceAllButton = QPushButton("Replace &all", self)
buttonsLayout.addWidget(self.replaceAllButton)
self.closeButton = QPushButton("C&lose", self)
buttonsLayout.addWidget(self.closeButton)
buttonsLayout.addStretch()
self.layout().addLayout(buttonsLayout, 0, 2, 5, 1)
self.__handleFromCursorChange(self.fromCursor.checkState())
self.setTextEdit(textEdit)
self.closeButton.released.connect(self.accept)
self.findButton.released.connect(self.__handleFind)
if withReplace:
self.replaceButton.released.connect(self.__handleReplace)
self.replaceAllButton.released.connect(self.__handleReplaceAll)
self.fromCursor.stateChanged.connect(self.__handleFromCursorChange)
def setTextEdit(self, textEdit):
self.__textEdit = textEdit
textCursor = self.__textEdit.textCursor()
textCursor.clearSelection()
self.__textEdit.setTextCursor(textCursor)
self.statusLabel.clear()
def __handleFind(self):
self.statusLabel.clear()
findFlags = QTextDocument.FindFlags()
if not self.fromCursor.isChecked() and\
self.dirUp.isChecked():
findFlags |= QTextDocument.FindBackward
if self.caseSensitive.isChecked():
findFlags |= QTextDocument.FindCaseSensitively
if self.wholeWords.isChecked():
findFlags |= QTextDocument.FindWholeWords
if not self.fromCursor.isChecked():
# Move the cursor to the start of the document.
textCursor = self.__textEdit.textCursor()
textCursor.setPosition(0)
self.__textEdit.setTextCursor(textCursor)
found = False
if self.regEx.isChecked():
# Find regular expression.
re = QRegExp(self.findText.text(),
Qt.CaseSensitive if self.caseSensitive.isChecked() else\
Qt.CaseInsensitive)
# QPlainTextEdit.find(QRegExp) is >= Qt 5.3.
# So use the QTextDocument's find instead.
textCursor = self.__textEdit.document().find(re,
self.__textEdit.textCursor(), findFlags)
if not textCursor.isNull():
self.__textEdit.setTextCursor(textCursor)
found = True
else:
# Find plain text.
found = self.__textEdit.find(self.findText.text(), findFlags)
if not found:
if self.fromCursor.isChecked():
# The next find should start at the beginning.
textCursor = self.__textEdit.textCursor()
textCursor.setPosition(0)
self.__textEdit.setTextCursor(textCursor)
self.statusLabel.setText("Reached end of document. "
"Text not found.")
def __handleReplace(self):
self.statusLabel.clear()
textCursor = self.__textEdit.textCursor()
result = False
if textCursor.hasSelection():
textCursor.insertText(self.replaceText.text())
result = True
self.__handleFind()
return result
def __handleReplaceAll(self):
self.statusLabel.clear()
count = 0
while True:
if self.__handleReplace():
count += 1
if not self.__textEdit.textCursor().hasSelection():
break
if count == 1:
self.statusLabel.setText("1 occurrence replaced.")
elif count > 1:
self.statusLabel.setText("%d occurrences replaced." % count)
else:
self.statusLabel.setText("Reached end of document. "
"Text not found.")
def __handleFromCursorChange(self, state):
self.dirUp.setEnabled(state == Qt.Checked)
self.dirDown.setEnabled(state == Qt.Checked)
self.findButton.setText("&Find next" if state == Qt.Checked else "&Find")
# AUTOMATICALLY GENERATED FILE
# DO NOT EDIT
# Generated from edit-find-4.svg
icon_find = b'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAA'\
b'BHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAA'\
b'CnxJREFUaIHtmV1sFNcVx393Znf20+u1vdjYYBIjYwJ4gbqt'\
b'cShNEEWEAkFIxYRGidSHKgpqhKqmUtq3vpRKSR8Soj5EDVJa'\
b'VYmURCU0EhLEpYBVWkpxHbwYQjAQkzj+wGv8sTs7uzNz+2Bm'\
b'tV52vbZJ3nKko7lzv87/P+ee+zXwjXwjDySiWMHrr79eVVZW'\
b'9qFt28sVRcFRKSVSSizLQkqJbduYpplNO/mWZc2o45RZloVt'\
b'2/fVcfKdek7a6/Xesm173+HDh/sL4XQVIxAIBDqeeOKJ9ZFI'\
b'ZE5fQko55/z51B0bG6s5dOhQB9BUqE1RAul0enlFRQXDw8OY'\
b'ppk14PF4yGQy2XpCiJLp2fKKiZQSIQSVlZVMTEw0FKtXlIDz'\
b'NRyXCiGwLAtN07BtOwvGMVQonQ869wsXIjMfz5QkkCuOsWLP'\
b'2dLFwM5mZz7tSnqgFPivcwjNRUoSyDVcCPTVq1dnBTYf0ACr'\
b'Vq3KtnsgD9i2PQNAsWeuwWKg50siv92CYmA+HihkdDZAs8nq'\
b'1atL1smVogQsy5phNPeZC6SUBxYSC4VmsGJScgjldpQPTErJ'\
b'lStXHjhgc2XNmjUF7RWTOQ0hp7P8jhVFybq81Kw0V0BzwZIr'\
b'8/JAbtrxQG4MzAVgqTrNzc33DaEFE8hdWQuRcDxQjGAp0KVW'\
b'6QeOAaeD0dFRgsEgmqbNMJLvgdkAzlWi0eh9eQ80jQohSCaT'\
b'hMPh7HsxD5TyRH7ZXGwvmEBuDCxduhSfz0cqlZoBwpmFZgM3'\
b'MTFBPB5nYmICKSXBYJB4PE4gEKC8vJxIJILX683Wj0aj95F/'\
b'YAKqqma30LkAFUUpOO0JIRgZGeHs2bOsXLmS1tZWKioqcLvd'\
b'GIaBpmkkEgkGBwfp6OigurqaRx99FL/fn+07F/SCCOQvZPkA'\
b'nY57e3vvqzc4OMj4+Dj79u0D4JP+Ud4+dZ3+4QQZS1IV8rBu'\
b'eSUb19Ry4MABuru7effdd1mxYgWbNm3KTh5fySxUikRzc/OM'\
b'vO7ubhRF4bnnnuPfH1/ntaO9jExmaKiroG5RGFVVGB5L8vbZ'\
b'fg4fu8r+x+p5dvs6qqurOXr0KA0NDSxZsmQGlgfeCxUjARCL'\
b'xbLvY2NjGIZBe3s7bx//L388eYONa5dy4LvLWLqoDAFkTJtU'\
b'2uSL0Sk+7hvh+MUB/nfjDL/76Uba29t555132Lt3L8FgcE4e'\
b'UIoV5MZAMRJCCKLRKNFolKamJm7dusXu3bs5ee4KRz66xU+e'\
b'bOH53etZ/fAiQn4vXo+Gx6Ph93l5uLaSba2N/Hj7OnRL5Td/'\
b'Pk95eZhNmzZx5syZOQ+hogScGMgHni+xWIyenh5Onz7Nli1b'\
b'GBuf5Pd/vcKW79TTtrIKpAUSJCAQKGJahRC4FIXaSj/fb2ng'\
b'xqDOB6cvE41G0XWdwcHBWT9mSQL5jYrFQTQapbm5mZGREerr'\
b'6/nw3A2qK4NsbmlA09wIRSVjSSxLYmdjavo+R1EgbdooimDD'\
b'2mX85fQtDCPN+vXrZyyQCx5CuVuJYiQAxsfHCYVCAPyjZ4RV'\
b'yxcRDnqwLIllSyzLxrJt7Ht3SgCKmO5DNzJoLpW6SIiEYfHp'\
b'7TssXryY/v7+LPgFESjWqBCJeDxOJBIhlTL4bHCKZTXl2LYD'\
b'Xk6Dt2XefgeMtIVtg+YSaG5BbVWQK5/Fs1sWXdeLAndkTgtZ'\
b'LBZjyZIlM7YTDsnLly8zNDREeXk5KcMgY9kk9QRTCT+aS+BS'\
b'BIqY/uIg7xGzSWcsPv18FN2wMCWYtkBIm/GE4dzIYRjGwgnk'\
b'BnF9fT2RSIR0Op3Nc0hEo1Hcbjfj4+N4PR4URcHl9uHWPGhu'\
b'Bbeq4FLvEVEEAjAtmzsTBkvqNNKmTSpjT8fC1TgBj4tMJpO9'\
b'i/pKCITD4YIdSimJxWLcvXsXXdfxej0sjfi4+fkQEf/0iutS'\
b'BKoCLiGRSBKJJPHxBKYNGRtMS5CRgowFg3cmWV73EFJKJicn'\
b'KSsrWziBudzLKIpCNBrFMAzef/99VFVl05pFxG7rpPEwkVYp'\
b'87lQXSpCFbgVQbCsnOoaSGXse2qRytj0D06AkDTVV/DlwADB'\
b'YBC3271wAoVmIbj/EBKLxQDQNI3h4WF+9Fgjf3v5NH39fqqC'\
b'btyKxK2CW5G4FHAr02uCaQsyNmRsQdqEExcG2LdpGV6Ph+7u'\
b'bpqaCt7lzo9AKRFCsHbtWmB6mJ07d4729nae37mSP/39Js/u'\
b'WEd5wI3XreJxK2guBZeigADTkqRNSSpj8dF/buLXVPZvXcOt'\
b'Wze5dOkSe/bs+foJSCnp6enJkjEMg66uLtp/0MZgPMFbH3ax'\
b'eX0ttWE3qgLqvQVMCIENpAxJZ+8dJpNp/nDwcdJpg/PnzzM5'\
b'OcnNmzd55JFHvhoCxYaR4wHnvbGxkaNHjxIIBPj5/u+xYkkv'\
b'r33QS1XYz6qGRdRWBfBoLu5OGFz/YoxL14d4bE2EX+5/HDNj'\
b'YBgGq1atIhQK8eqrr/L000+zefPmBydQTBwP5BJsbGyks7OT'\
b'qakpHv/WetrW1NHZM8A/Y1/S88kX2fNAS+Mifrbze6x4aDG3'\
b'b99G13Xi8Xj2fLFr1y6OHTvG8PDwrBiKTrTPPPPM+BtvvBFK'\
b'JpNZMs4Ck3vYyb8vEkIwNTVFR0cHLpeLtrY2qqqq8Hg8eDwe'\
b'DMNAVVUMw0DXdS5cuEBnZyetra34/X4mJiZIJBKkUikqKiro'\
b'6uoiFovZQ0ND3osXL2bycc66DjhTaf5sVOo9GAyyZ88erl27'\
b'xqlTp5BSEolECAaD+Hw+EokEo6Oj9PX1UVtby+7du3nzzTfZ'\
b'sWMHgUAAKSVut5t4PE5LSwvhcFg5e/bs8a1bt+7t6OgYn5MH'\
b'nnrqqfEjR46EdF3PLmKOB0zTLPr1C92hjo6OZo+ZpmmiaRrh'\
b'cJjly5cTCAQAuH79OocOHWLnzp1UVlZy9+5dFEUhHo/j/Oo6'\
b'fvz4ZdM0d3R0dGR/+BUioAD+vXv3Drz11ltl+QQ8Hk/2fTbw'\
b'MPNYmn9IL7RNGBkZ4ZVXXmHDhg0sW7aMeDyOz+djaGiIUChE'\
b'MpnkvffeGwR2njhxossBmyt+YBFQbdu2yDc8m0gpMU2TTCaD'\
b'YRikUikMw8iOdUeTySS6rpNIJGZoMpkkGAzy0ksv0dvbS09P'\
b'D5WVlRiGQXV1NVNTU9TV1fHiiy8uVhTlxPbt20MAag4GDQgC'\
b'ZUCopaXlyW3btlWEQiF8Ph9erxev14umadmA1DQNTdNQVRVF'\
b'UWbsUh11/vc6PwsdkqZpzlCn3OVy0draysWLF7lx4wZNTU3o'\
b'uk5NTQ0rVqygvr6eVCrlv3bt2sW+vr4ruUGc+6llf3//ywcP'\
b'Hvytruv37ajyA7iQFigThfKd/goMSSmlVMfGxpRdu3Zlbyos'\
b'yyIUCiGE0ACRSyADJJiOC9nZ2dnpcrl+GHKOWrMffgSgSimV'\
b'e+2VnLR6r1xYlpUtL9SNo6qq2kIICzDv3LmzcWxs7BcvvPCC'\
b'WlNTw8DAACdPntQzmcwpQBYKYgF4AR/gZnqYFTOa3y4XYK6K'\
b'vHJHc8HnkrAB897TaGtr+3Z5efmvVFVtsCyrF/j1iRMn/gWz'\
b'TKNFAM5HcomIAlpIJDNJOOrk3Sf/B0Tutubulfg0AAAAAElF'\
b'TkSuQmCC'
# AUTOMATICALLY GENERATED FILE
# DO NOT EDIT
# Generated from edit-find-replace-3.svg
icon_findreplace = b'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAA'\
b'BHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAA'\
b'D2JJREFUaIHtmXlwXdV9xz/n3O09Pelps/bdErZsWZYNsU0N'\
b'BlIwBELASdjimALptE2bpA1pkmbSkgAhSUuSTicTCKVt2hSC'\
b'CSSAXJulEwpJCSAMNl60oMWSJcuylifpLXr7vad/vEWSkWwn'\
b'ZJLpTM7MfXe/5/v9/r7nd5YHvy+/L++piDPdfKr9yUcdx96a'\
b'SCQaUKlratETatGFs90zDWPIcZQlBD2JRHL3rp23/ct7Qs8Z'\
b'CDz19I8fbW5u2dnUtEoYuvFe6wFgLjKHnUwyM+tjaGggenJs'\
b'zNbQPn/zzbse+nW/uSyBnzy9+9h11360we+fAUChUEqhUKAU'\
b'8ViCwcEhTpwYZfzUOMlkEgDDMCgtK6GyqoKa2mo0TUu9rRRK'\
b'ga7ruF05uFw5zM746B3o8fumZl68+YadH/2NEvjR4/+pdt58'\
b'K5O+8bQbUn6wbZuuzi6OHO5ky5YtnHfeeXi9XgwjFaVEIoHf'\
b'76evr4+Ojg7WrV9L03mNi0Swk0kcB6oqqpmLhOjueseZmBrt'\
b'vuWGW9f95gjs/qHaecsfMTE1TsbM4XCYZ/c+T2trKxdeeCGJ'\
b'RIJQKEQ0GsW2bSClsGVZ5OXloWkar732Gn19vWy79GJMy8hG'\
b'MRSaQ5Ma9bUrCQRnGTlxnP7+Xt+uj31ixa9CQF/uhsq2wJRq'\
b'4XCEnz75FDfeeCMVFRVMTEzQc9zHs2+e4shxP1OBOAJFkdfF'\
b'+nov11xQRnPdCrZu3UpdXR3t7e1cdc12TNNEKDB0nbm5Oaan'\
b'fRQUFFBeVoHbnVP86BOPDO666daG904gk3WUwnEcnn/2BW68'\
b'8UZKS0sZGh7hoWf7OXjMz6r6Qi7aWE2e2wQgGI4zOhnivid6'\
b'uGBlPn92zSpqqiu5/vrree7557jgfRswTAMhJI7tMD4xRnVV'\
b'NfFEnHgiTkvzmvpHH/vByV07P1H5nghkGCilOHq0k/Xr11NZ'\
b'Wcng8WHu2d2FZprs+mArtSV5rPC68VgauiaJJWwmA1H6Tszy'\
b'0oEhvvZ4F3fdAvV1NbSsbcHvD9DY1Ijj2AgBkUiUpG2T484h'\
b'Fo8ihKC+obFi9xOPvPyxm2697GwE5PL4UwRisThdR7vZvHkz'\
b'ExMTPLSvD0cILj+/mjVVXoo8BoZUgEKTkJ9jsKrCyx+2VXLl'\
b'plqijuLh595hYmKCTZs20Xmkm5HhESYmJpmd9RONRlBKYZku'\
b'3JYbKSXl5eXk5eZv3f3jR77x6xNI7wePDbJ582bi8Tg9x30c'\
b'Ggpx8fn1NFYV47IsLNPAMnVMQ8PQNXRdQ9MklqmztaWa7Vsa'\
b'eXMgSN/INPF4nA0bNqCUoqK8nJKSFXi9+Rw4uJ9XXv05Xd2d'\
b'+Gf9AKxZ22y4cj13/Ot/PHQJwOiWqi9NbWzt97W19c62tX17'\
b'fO3aXDgHC504Mcpll15GMBhk7/5RGmvyiUVjBENhDGEhlYZE'\
b'IpSGcBxsTYASJB2FY9tUFFg0VHnZ0zHCqtpiqqur+fkvXkYI'\
b'sB0Hx3FwbBvbsXFshymfD8MwaGpqpLayujww6//e2JaqH+nR'\
b'gm8Gt15MbnU1+ltvfdocGNgEXHqGRpwiMO2bxu12EwqF6BwJ'\
b'cfnmJgryXCQRuCwT05DoUqJpEiEFIFBCgRAgJGVFeaysLuaX'\
b'B4aJx+Pk5OQQi8Wpq68jmbSJRaNEo1GisSixaAwRjRGNRuk8'\
b'2kVb23o8nQfXvHTZLX+fG4tTW1KO5vVib99uGUODF8ysWtVw'\
b'hjSaIhGPxxFCYNs2Pn8MU0sSDYc4FQ1R4AKPpWPoGpoUaFKC'\
b'ECjAcSBhOyhHYUiHSX8Ux3EQQhCeCzM8PAKA4zhIKdB1HU+O'\
b'B48nF02ThIIhjjzzJOOl1fr7tl7CiYF+Xj82wKaAH5fUWKFL'\
b'3TAM7xktlIlCPB4HQEiBNzcXtyUwNUEkqSjOtzA0iZQCIQRK'\
b'gaNACYVQEiFt3G43Qsz3mVJK6uvr5pVaogx2HeRYUnDTDTdQ'\
b'U1NDvreAFyenODh+is3HjqNFwmahEt1n7AeklBiGQTSaSm9F'\
b'uSbjUzOsyDMwNIdISJEIB6go9qLJlIWUEtgKbAcStiIYSTI1'\
b'FaAoT0fKVM4wDJ3h48PvqlMKiWmZ+Ee6GRybosileOG5p2jd'\
b'sJnBY8cZGhmlrMhLYW+Xmqoa+9SK52fjZ+2JPbkeQqEQ+fn5'\
b'tNXnM+FP0FRTjKULXIbA1AU2Gl6PC4Qg6UAymbKPIxVORDEV'\
b'SrChIR/TNAmHw5SWllJf35CtaWFJnjiEfOELfPKyS8gtLcY3'\
b'Ncru1+c4ORGmsXEl/sA0k9WBL5zfPvt9OIcsVFNbw8DAABdd'\
b'dBHXbKrg3t1dNFe6cBlgSoWuKWY1GJMCyzQxDAukTsJWzEVt'\
b'Ts1E6Oyf4Gu7WvB4PPT392O5rCUioJATPbj2/TVNV1xJbmkR'\
b'yt+HKxBgY84wdul5zAV8NA298fD57YPfybx11qHE6tXn8dCD'\
b'D7Nt2zaaqgrYsrqYjndmuX5bPaYmMHWJoaf97ygSjiKWUMRt'\
b'RRzBa92TXLy2mMaqQkzTpLOzkw9+6Gp0fXHViZFD+J/7PPUL'\
b'wId9AeJaBUY0SNy2qZvc/82PPrjnywvfO6uFdF3jom1befHF'\
b'F7n22mv54ysT3PPYUX7yP728v60UlwFSpHpEh5T3bSUIxxW/'\
b'ODyOLhR3bF9NaWkpHR0dlJWXMjp6clFdcqIb67/uZOX2q8gt'\
b'KVwAvpywP8LYaIRq7Y2vf+xb7X93Os5le+JMCIQQlJaW8Ez7'\
b'M4yMjFBdVcFXd66jttjNYy8Nc3g4RlS5cXsLyfEWEsHFkeEI'\
b'T7w8TEOJm6/ubKW6qpKxsTEGhwb5g60X0tBQn92q9Vnc+z6X'\
b'Bl+wCHzEH2Pm6H7CxavZ9Q/vBn/mCKQtND09zV13fYXCwgK+'\
b'84/f4TOf/gyrV6/mU9dZXHVihn37R3n8Z+NMBxIAFHkN2ury'\
b'uGfnGpqqiygpKWFsbIx9+/bR2raO4eF574vxbsw9n10Avj8F'\
b'XpYR8cfwHemg/i8e45WOoWV1PqOF/AE/Dz74fdra1mNZFgD3'\
b'338/H/nIR7j66qspKipi7coyotEoyWQSIQSapuFyucjLy0NK'\
b'yRtvvMHg0CDXXndN9hsA8eG3md77OeqXAh+I4zvSQcHHHyB/'\
b'44dQHd/91Qkk4nG+evddNK9pZsPGNva27yUSjTLpm+S7DzzA'\
b'm2/u5/LLr6C1tZWysjIMIzXbSiaTBAIBDh06xIEDByivKGPV'\
b'qiZOjZ1Kyw5ivAuj/bM0XHEVuSu8S4Iv3PUArpYrF9vhXAns'\
b'2LGj+K23DtDa2sqaNWs4/PZhNl6wkWee3sv0TIB//7d/pqCg'\
b'gN7eXvY9u49QMJQe30t0XaeouJCamhp2fPh6DGNxFfHht5na'\
b'8znqM+ADA2nwpUSCCXxH3qBo1/dxrds+74bl8b+bwI4dO4ot'\
b't/76utZ1tKxroae7B09uDq/88nUCcxG++MU7GR4ZZmjoOEo5'\
b'rCgpoqSkGCEywwmJlJJoJEp/Xx9Sps41TUNM9mDu+at55QMD'\
b'hH3+lPLBJFOHXsf5wL1YLdtTQ48Fs8JzIpABv/H88+vXNDfT'\
b'0/0OHo+bN986xODQCHd+5s/xevORmkCTGlJIhJTz52mwUkik'\
b'JufPpSQ5egTf05+l8vLtuItycWb7icwEsuB9hzsoue0h3Ouu'\
b'SuFWasGSwzkQyIBva2urX7umWe/rG8A0dfa/+Ta9/YP85ac+'\
b'STAYIhgMIqVECJka/6SVl1JDSJG+lzrPjI/kZC/6vs+z8vLt'\
b'eIpySc4MEJ0NYMsyohnlr76X8dxmxPFhampqkHJ+8HdOFnK5'\
b'jZdb1rXUr25epQ8OHkcIePvwUXp6j3HdBz+AYycpLy9P22Gh'\
b'0lqWwMLrQqYIJk8eZWrfF6l7/xXkFOXi+I8RnQ2SlKUk5hxm'\
b'DndQevvD5LRedRrYedTnZCGlnMa6+jp9bGwc207Q0zvAqfFp'\
b'7rnry0xOThLwB4hGoxi6eZriGQLpqGjzx6bvKOK/v07dpe/P'\
b'go/NBnH0UhIRhe/Qa3DNfUzkrcbuH0jNF6Rk5cqG1Mh1CTLL'\
b'EojGkvf99Kd7/nbz5o053T19yWNDJ/Q/vf02Bvr7EUKQl59P'\
b'2/r1KAW2nSCZTC5QRmTnA5qmo0kNTdeIn/gheTfdSb4+geY7'\
b'SCwUQrPKiM8pZg6/TuHHH0Ct3EYinkDXNUzLwjTN1HKkAiXO'\
b'3UJ17U+3jzS3tLw6PjF5STgcC1SUFq5wHIeS0hKqa2qpKC9j'\
b'bGwcx0mtwGUmKCL9Y9sCASREao3UjI1TXJRH2RVfAjvK3LN/'\
b'gq1NEZlTTB58lbGNn+aYPw/9SCemqWOaJrphYlkmTY2NCCkR'\
b'WQJnj8AocLCns3MS+DYwfPs/favrjjvuYGp6ApFOB3V1NaeB'\
b'F1kGQmSvgBBED/4MvagZOzxFfKafZMVWIsN7mDz4KsFtf4Nn'\
b'5SUUGgaWZWGaBqZpYVomlmliOw5CKQSptVilnIxW72KSIZAE'\
b'jqa31I3scDctgxAMD49g205WmdNBZ/axcIBI9yE2XXkHoWMv'\
b'EB87RDI0jWMZ9K26nTDVGCMjGIaBYRjk5OTgcrmwLBNN16mt'\
b'qUlHIDUXt20HQEsTcBYSOeuqRCaZCaC2tuZd6i+OgkApxSPf'\
b'u5s7v7KbvfeHaVtTSTCYZDaWz0zuBlxldZTkeSksLCQvLxeX'\
b'25XKWulvyPTKRmZFXC2Ymy9WNEVi+RnZEi1/dHSURCI5/5Us'\
b'gXn1AX7+2tvc9uGtBIovpT+vDU+5l3yPh3K3G9M0s0vxjuMs'\
b'Eiujhcp+P5PRsoAWbpyRwFLtpqqqamnfn2alHzzWniWV+k4K'\
b'UubPEUhFSmrzqVKhENln0lqkR7fpCu2lcJ7VQhk1VPqjWXUW'\
b'Pbz4ogKEUiiRISdBgFxkyAzs9AtLHqvsSsZyZTkCxoKRVFqO'\
b'LBWUEgixYI/IAiadPZRIX0OAUKc5Ur37aCHwdL2nmUAnlWzO'\
b'SsAFuBdaSCmVbaBCLEeCbOgVYt6DSya/xWUh6PlztUBDBZAL'\
b'hIH4mQjogAXkWZZ1MpFIVGa9uYBEyt8LSaSQzh+ncZ8DeE5/'\
b'5DQSyWQSy3SdBDykUmgyvV+SgCSVbz3+WX/n/77ycsW2iy8T'\
b'mazx2y7JZIKXXn5RBYKBw6QIzHFaEzy9PerpB/OByq/dd/c3'\
b'cvPz1iUTiZLllDxTN//r3ssUy7Qm/IHAobu/cu+XgTEgCIRY'\
b'EIGl/qV0Ae70PhfIIRWV30VJkPL9HBBliTaw3N+sBmCSikim'\
b'C/9dFYcUkThLZKH/9+X/AInpD+rrWNZhAAAAAElFTkSuQmCC'
......@@ -35,6 +35,8 @@ download.png | network-server.svg and | CC-BY-SA 3.0 or
edit-4.svg | nuvola | LGPL-2.1
edit-copy-4.svg | tango | PD
edit-cut-4.svg | tango | PD
edit-find-4.svg | tango | PD
edit-find-replace-4.svg | tango | PD
edit-paste-4.svg | tango | PD
edit-redo-4.svg | tango | PD
edit-undo-4.svg | tango | PD
......
This diff is collapsed.
This diff is collapsed.
......@@ -2,7 +2,7 @@
#
# AWL simulator - GUI icons
#
# Copyright 2014 Michael Buesch <m@bues.ch>
# Copyright 2014-2015 Michael Buesch <m@bues.ch>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -61,6 +61,8 @@ from awlsim.gui.icons.doc_export import *
from awlsim.gui.icons.doc_import import *
from awlsim.gui.icons.doc_new import *
from awlsim.gui.icons.tab_new import *
from awlsim.gui.icons.find import *
from awlsim.gui.icons.findreplace import *
import base64
......@@ -103,6 +105,8 @@ __icons = {
"doc_import" : icon_doc_import,
"doc_new" : icon_doc_new,
"tab_new" : icon_tab_new,
"find" : icon_find,
"findreplace" : icon_findreplace,
}
def getIcon(iconName):
......
......@@ -275,6 +275,12 @@ class MainWidget(QWidget):
def paste(self):
self.projectWidget.clipboardPaste()
def findText(self):
self.projectWidget.findText()
def findReplaceText(self):
self.projectWidget.findReplaceText()
class MainWindow(QMainWindow):
@classmethod
def start(cls,
......@@ -306,6 +312,10 @@ class MainWindow(QMainWindow):
self.tbCopyAct = self.tb.addAction(getIcon("copy"), "Copy", self.copy)
self.tbPasteAct = self.tb.addAction(getIcon("paste"), "Paste", self.paste)
self.tb.addSeparator()
self.tbFindAct = self.tb.addAction(getIcon("find"), "Find...", self.findText)
self.tbFindReplaceAct = self.tb.addAction(getIcon("findreplace"),
"Find and replace...", self.findReplaceText)
self.tb.addSeparator()
self.tbLibAct = self.tb.addAction(getIcon("stdlib"), "Standard library", self.openLibrary)
self.addToolBar(Qt.TopToolBarArea, self.tb)
......@@ -333,6 +343,10 @@ class MainWindow(QMainWindow):
self.cutAct = menu.addAction(getIcon("cut"), "&Cut", self.cut)
self.copyAct = menu.addAction(getIcon("copy"), "&Copy", self.copy)
self.pasteAct = menu.addAction(getIcon("paste"), "&Paste", self.paste)
menu.addSeparator()
self.findAct = menu.addAction(getIcon("find"), "&Find...", self.findText)
self.findReplaceAct = menu.addAction(getIcon("findreplace"),
"Find and r&eplace...", self.findReplaceText)
self.menuBar().addMenu(menu)
menu = QMenu("&Library", self)
......@@ -378,6 +392,7 @@ class MainWindow(QMainWindow):
menu.addAction(getIcon("cpu"), "&About...", self.about)
self.menuBar().addMenu(menu)
self.__sourceTextHasFocus = False
self.__dirtyChanged(False)
self.__selResourceChanged(ProjectWidget.RES_SOURCES)
self.__textFocusChanged(False)
......@@ -441,6 +456,19 @@ class MainWindow(QMainWindow):
def __handleProjectLoaded(self, project):
self.__updateLibActions()
self.__updateFindActions()
def __updateFindActions(self):
if self.__selProjectResource == ProjectWidget.RES_SOURCES:
self.tbFindAct.setEnabled(True)
self.tbFindReplaceAct.setEnabled(True)
self.findAct.setEnabled(True)
self.findReplaceAct.setEnabled(True)
else:
self.tbFindAct.setEnabled(False)
self.tbFindReplaceAct.setEnabled(False)
self.findAct.setEnabled(False)
self.findReplaceAct.setEnabled(False)
def __updateLibActions(self):
# Enable/disable the library toolbar button.
......@@ -461,10 +489,12 @@ class MainWindow(QMainWindow):
def __textFocusChanged(self, textHasFocus):
self.__sourceTextHasFocus = textHasFocus
self.__updateLibActions()
self.__updateFindActions()
def __selResourceChanged(self, resourceNumber):
self.__selProjectResource = resourceNumber
self.__updateLibActions()
self.__updateFindActions()
def __updateUndoActions(self):
self.undoAct.setEnabled(
......@@ -588,3 +618,9 @@ class MainWindow(QMainWindow):
def paste(self):
self.centralWidget().paste()
def findText(self):
self.centralWidget().findText()
def findReplaceText(self):
self.centralWidget().findReplaceText()
......@@ -480,3 +480,13 @@ class ProjectWidget(QTabWidget):
widget = self.currentWidget()
if widget:
widget.clipboardPaste()
def findText(self):
widget = self.currentWidget()
if widget:
widget.findText()
def findReplaceText(self):
widget = self.currentWidget()
if widget:
widget.findReplaceText()
......@@ -24,6 +24,7 @@ from awlsim.common.compat import *
from awlsim.gui.editwidget import *
from awlsim.gui.symtabwidget import *
from awlsim.gui.finddialog import *
from awlsim.gui.util import *
......@@ -210,6 +211,12 @@ class SourceTabWidget(QTabWidget):
def clipboardPaste(self):
pass
def findText(self):
pass
def findReplaceText(self):
pass
def handleIdentsMsg(self, identsMsg):
pass
......@@ -461,6 +468,20 @@ class AwlSourceTabWidget(SourceTabWidget):
if editWidget:
editWidget.paste()
def findText(self):
editWidget = self.currentWidget()
if editWidget:
dlg = FindReplaceDialog(editWidget, False, editWidget)
dlg.exec_()
dlg.deleteLater()
def findReplaceText(self):
editWidget = self.currentWidget()
if editWidget:
dlg = FindReplaceDialog(editWidget, True, editWidget)
dlg.exec_()
dlg.deleteLater()
def handleIdentsMsg(self, identsMsg):
SourceTabWidget.handleIdentsMsg(self, identsMsg)
for editWidget in self.allTabWidgets():
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment