142 self.ui.findtextCombo.addAction(self.findPrevAct) |
142 self.ui.findtextCombo.addAction(self.findPrevAct) |
143 |
143 |
144 self.havefound = False |
144 self.havefound = False |
145 self.__pos = None |
145 self.__pos = None |
146 self.__findBackwards = False |
146 self.__findBackwards = False |
147 self.__selection = None |
147 self.__selections = [] |
148 self.__finding = False |
148 self.__finding = False |
149 |
149 |
|
150 def __selectionBoundary(self, selections=None): |
|
151 """ |
|
152 Private method to calculate the current selection boundary. |
|
153 |
|
154 @param selections optional parameter giving the selections to |
|
155 calculate the boundary for (list of tuples of four integer) |
|
156 @return tuple of start line and index and end line and index |
|
157 (tuple of four integer) |
|
158 """ |
|
159 if selections is None: |
|
160 selections = self.__selections |
|
161 if selections: |
|
162 lineNumbers = [sel[0] for sel in selections] + \ |
|
163 [sel[2] for sel in selections] |
|
164 indexNumbers = [sel[1] for sel in selections] + \ |
|
165 [sel[3] for sel in selections] |
|
166 startLine, startIndex, endLine, endIndex = ( |
|
167 min(lineNumbers), min(indexNumbers), |
|
168 max(lineNumbers), max(indexNumbers)) |
|
169 else: |
|
170 startLine, startIndex, endLine, endIndex = -1, -1, -1, -1 |
|
171 |
|
172 return startLine, startIndex, endLine, endIndex |
|
173 |
150 def on_findtextCombo_editTextChanged(self, txt): |
174 def on_findtextCombo_editTextChanged(self, txt): |
151 """ |
175 """ |
152 Private slot to enable/disable the find buttons. |
176 Private slot to enable/disable the find buttons. |
153 """ |
177 """ |
154 if not txt: |
178 if not txt: |
276 lineFrom, indexFrom, lineTo, indexTo) |
297 lineFrom, indexFrom, lineTo, indexTo) |
277 while ok: |
298 while ok: |
278 tgtPos, tgtLen = aw.getFoundTarget() |
299 tgtPos, tgtLen = aw.getFoundTarget() |
279 if tgtLen == 0: |
300 if tgtLen == 0: |
280 break |
301 break |
281 aw.setSearchIndicator(tgtPos, tgtLen) |
302 if len(self.__selections) > 1: |
|
303 lineFrom, indexFrom = aw.lineIndexFromPosition(tgtPos) |
|
304 lineTo, indexTo = aw.lineIndexFromPosition(tgtPos + tgtLen) |
|
305 for sel in self.__selections: |
|
306 if lineFrom == sel[0] and \ |
|
307 indexFrom >= sel[1] and \ |
|
308 indexTo <= sel[3]: |
|
309 indicate = True |
|
310 break |
|
311 else: |
|
312 indicate = False |
|
313 else: |
|
314 indicate = True |
|
315 if indicate: |
|
316 aw.setSearchIndicator(tgtPos, tgtLen) |
282 ok = aw.findNextTarget() |
317 ok = aw.findNextTarget() |
283 |
318 |
284 def __findNextPrev(self, txt, backwards): |
319 def __findNextPrev(self, txt, backwards): |
285 """ |
320 """ |
286 Private method to find the next occurrence of the search text. |
321 Private method to find the next occurrence of the search text. |
297 aw = self.viewmanager.activeWindow() |
332 aw = self.viewmanager.activeWindow() |
298 cline, cindex = aw.getCursorPosition() |
333 cline, cindex = aw.getCursorPosition() |
299 |
334 |
300 ok = True |
335 ok = True |
301 lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() |
336 lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() |
|
337 boundary = self.__selectionBoundary() |
302 if backwards: |
338 if backwards: |
303 if self.ui.selectionCheckBox.isChecked() and \ |
339 if self.ui.selectionCheckBox.isChecked() and \ |
304 (lineFrom, indexFrom, lineTo, indexTo) == self.__selection: |
340 (lineFrom, indexFrom, lineTo, indexTo) == boundary: |
305 # initial call |
341 # initial call |
306 line = self.__selection[2] |
342 line, index = boundary[2:] |
307 index = self.__selection[3] |
|
308 else: |
343 else: |
309 if (lineFrom, indexFrom) == (-1, -1): |
344 if (lineFrom, indexFrom) == (-1, -1): |
310 # no selection present |
345 # no selection present |
311 line = cline |
346 line = cline |
312 index = cindex |
347 index = cindex |
313 else: |
348 else: |
314 line = lineFrom |
349 line = lineFrom |
315 index = indexFrom - 1 |
350 index = indexFrom - 1 |
316 if self.ui.selectionCheckBox.isChecked() and \ |
351 if self.ui.selectionCheckBox.isChecked() and \ |
317 line == self.__selection[0] and \ |
352 line == boundary[0] and \ |
318 index >= 0 and \ |
353 index >= 0 and \ |
319 index < self.__selection[1]: |
354 index < boundary[1]: |
320 ok = False |
355 ok = False |
321 |
356 |
322 if ok and index < 0: |
357 if ok and index < 0: |
323 line -= 1 |
358 line -= 1 |
324 if self.ui.selectionCheckBox.isChecked(): |
359 if self.ui.selectionCheckBox.isChecked(): |
325 if line < self.__selection[0]: |
360 if line < boundary[0]: |
326 if self.ui.wrapCheckBox.isChecked(): |
361 if self.ui.wrapCheckBox.isChecked(): |
327 line = self.__selection[2] |
362 line, index = boundary[2:] |
328 index = self.__selection[3] |
|
329 else: |
363 else: |
330 ok = False |
364 ok = False |
331 else: |
365 else: |
332 index = aw.lineLength(line) |
366 index = aw.lineLength(line) |
333 else: |
367 else: |
358 not backwards, |
391 not backwards, |
359 line, index) |
392 line, index) |
360 |
393 |
361 if ok and self.ui.selectionCheckBox.isChecked(): |
394 if ok and self.ui.selectionCheckBox.isChecked(): |
362 lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() |
395 lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() |
363 if (lineFrom == self.__selection[0] and indexFrom >= self.__selection[1]) or \ |
396 if len(self.__selections) > 1: |
364 (lineFrom > self.__selection[0] and lineFrom < self.__selection[2]) or \ |
397 for sel in self.__selections: |
365 (lineFrom == self.__selection[2] and indexFrom <= self.__selection[3]): |
398 if lineFrom == sel[0] and \ |
|
399 indexFrom >= sel[1] and \ |
|
400 indexTo <= sel[3]: |
|
401 ok = True |
|
402 break |
|
403 else: |
|
404 ok = False |
|
405 elif (lineFrom == boundary[0] and indexFrom >= boundary[1]) or \ |
|
406 (lineFrom > boundary[0] and lineFrom < boundary[2]) or \ |
|
407 (lineFrom == boundary[2] and indexFrom <= boundary[3]): |
366 ok = True |
408 ok = True |
367 else: |
409 else: |
368 if self.ui.wrapCheckBox.isChecked(): |
410 ok = False |
369 # try it again |
411 if not ok and len(self.__selections) > 1: |
370 if backwards: |
412 # try again |
371 line = self.__selection[2] |
413 while not ok and \ |
372 index = self.__selection[3] |
414 ((backwards and lineFrom >= boundary[0]) or \ |
|
415 (not backwards and lineFrom <= boundary[2])): |
|
416 for ind in range(len(self.__selections)): |
|
417 if lineFrom == self.__selections[ind][0]: |
|
418 after = indexTo > self.__selections[ind][3] |
|
419 if backwards: |
|
420 if after: |
|
421 line, index = self.__selections[ind][2:] |
|
422 else: |
|
423 if ind > 0: |
|
424 line, index = self.__selections[ind - 1][2:] |
|
425 else: |
|
426 if after: |
|
427 if ind < len(self.__selections) - 1: |
|
428 line, index = self.__selections[ind + 1][:2] |
|
429 else: |
|
430 line, index = self.__selections[ind][:2] |
|
431 break |
373 else: |
432 else: |
374 line = self.__selection[0] |
433 break |
375 index = self.__selection[1] |
|
376 ok = aw.findFirst(txt, |
434 ok = aw.findFirst(txt, |
377 self.ui.regexpCheckBox.isChecked(), |
435 self.ui.regexpCheckBox.isChecked(), |
378 self.ui.caseCheckBox.isChecked(), |
436 self.ui.caseCheckBox.isChecked(), |
379 self.ui.wordCheckBox.isChecked(), |
437 self.ui.wordCheckBox.isChecked(), |
380 self.ui.wrapCheckBox.isChecked(), |
438 self.ui.wrapCheckBox.isChecked(), |
381 not backwards, |
439 not backwards, |
382 line, index) |
440 line, index) |
383 if ok: |
441 if ok: |
384 lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() |
442 lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() |
385 if (lineFrom == self.__selection[0] and \ |
443 if lineFrom < boundary[0] or lineFrom > boundary[2] or \ |
386 indexFrom >= self.__selection[1]) or \ |
444 indexFrom < boundary[1] or indexFrom > boundary[3] or \ |
387 (lineFrom > self.__selection[0] and \ |
445 indexTo < boundary[1] or indexTo > boundary[3]: |
388 lineFrom < self.__selection[2]) or \ |
446 ok = False |
389 (lineFrom == self.__selection[2] \ |
447 break |
390 and indexFrom <= self.__selection[3]): |
448 if not ok: |
|
449 if self.ui.wrapCheckBox.isChecked(): |
|
450 # try it again |
|
451 if backwards: |
|
452 line, index = boundary[2:] |
|
453 else: |
|
454 line, index = boundary[:2] |
|
455 ok = aw.findFirst(txt, |
|
456 self.ui.regexpCheckBox.isChecked(), |
|
457 self.ui.caseCheckBox.isChecked(), |
|
458 self.ui.wordCheckBox.isChecked(), |
|
459 self.ui.wrapCheckBox.isChecked(), |
|
460 not backwards, |
|
461 line, index) |
|
462 if ok: |
|
463 lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() |
|
464 if len(self.__selections) > 1: |
|
465 for sel in self.__selections: |
|
466 if lineFrom == sel[0] and \ |
|
467 indexFrom >= sel[1] and \ |
|
468 indexTo <= sel[3]: |
|
469 ok = True |
|
470 break |
|
471 else: |
|
472 ok = False |
|
473 elif (lineFrom == boundary[0] and \ |
|
474 indexFrom >= boundary[1]) or \ |
|
475 (lineFrom > boundary[0] and \ |
|
476 lineFrom < boundary[2]) or \ |
|
477 (lineFrom == boundary[2] \ |
|
478 and indexFrom <= boundary[3]): |
391 ok = True |
479 ok = True |
392 else: |
480 else: |
393 ok = False |
481 ok = False |
394 aw.selectAll(False) |
|
395 aw.setCursorPosition(cline, cindex) |
|
396 aw.ensureCursorVisible() |
|
397 else: |
482 else: |
398 ok = False |
483 ok = False |
399 aw.selectAll(False) |
484 |
400 aw.setCursorPosition(cline, cindex) |
485 if not ok: |
401 aw.ensureCursorVisible() |
486 aw.selectAll(False) |
|
487 aw.setCursorPosition(cline, cindex) |
|
488 aw.ensureCursorVisible() |
402 |
489 |
403 self.__finding = False |
490 self.__finding = False |
404 |
491 |
405 return ok |
492 return ok |
406 |
493 |
452 Public slot to update the selection check box. |
539 Public slot to update the selection check box. |
453 |
540 |
454 @param editor reference to the editor (Editor) |
541 @param editor reference to the editor (Editor) |
455 """ |
542 """ |
456 if not self.__finding: |
543 if not self.__finding: |
457 if editor.hasSelectedText() and not editor.selectionIsRectangle(): |
544 if editor.hasSelectedText(): |
458 line1, index1, line2, index2 = editor.getSelection() |
545 selections = editor.getSelections() |
|
546 line1, index1, line2, index2 = self.__selectionBoundary(selections) |
459 if line1 != line2: |
547 if line1 != line2: |
460 self.ui.selectionCheckBox.setEnabled(True) |
548 self.ui.selectionCheckBox.setEnabled(True) |
461 self.ui.selectionCheckBox.setChecked(True) |
549 self.ui.selectionCheckBox.setChecked(True) |
462 self.__selection = (line1, index1, line2, index2) |
550 self.__selections = selections |
463 return |
551 return |
464 |
552 |
465 self.ui.selectionCheckBox.setEnabled(False) |
553 self.ui.selectionCheckBox.setEnabled(False) |
466 self.ui.selectionCheckBox.setChecked(False) |
554 self.ui.selectionCheckBox.setChecked(False) |
467 self.__selection = None |
555 self.__selections = [] |
468 |
556 |
469 @pyqtSlot() |
557 @pyqtSlot() |
470 def on_replaceButton_clicked(self): |
558 def on_replaceButton_clicked(self): |
471 """ |
559 """ |
472 Private slot to replace one occurrence of text. |
560 Private slot to replace one occurrence of text. |
546 self.ui.replacetextCombo.clear() |
634 self.ui.replacetextCombo.clear() |
547 self.ui.replacetextCombo.addItems(self.replaceHistory) |
635 self.ui.replacetextCombo.addItems(self.replaceHistory) |
548 |
636 |
549 aw = self.viewmanager.activeWindow() |
637 aw = self.viewmanager.activeWindow() |
550 cline, cindex = aw.getCursorPosition() |
638 cline, cindex = aw.getCursorPosition() |
|
639 boundary = self.__selectionBoundary() |
551 if self.ui.selectionCheckBox.isChecked(): |
640 if self.ui.selectionCheckBox.isChecked(): |
552 line = self.__selection[0] |
641 line, index = boundary[:2] |
553 index = self.__selection[1] |
|
554 else: |
642 else: |
555 line = 0 |
643 line = 0 |
556 index = 0 |
644 index = 0 |
557 ok = aw.findFirst(ftxt, |
645 ok = aw.findFirst(ftxt, |
558 self.ui.regexpCheckBox.isChecked(), |
646 self.ui.regexpCheckBox.isChecked(), |
560 self.ui.wordCheckBox.isChecked(), |
648 self.ui.wordCheckBox.isChecked(), |
561 False, True, line, index) |
649 False, True, line, index) |
562 |
650 |
563 if ok and self.ui.selectionCheckBox.isChecked(): |
651 if ok and self.ui.selectionCheckBox.isChecked(): |
564 lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() |
652 lineFrom, indexFrom, lineTo, indexTo = aw.getSelection() |
565 if (lineFrom == self.__selection[0] and indexFrom >= self.__selection[1]) or \ |
653 if (lineFrom == boundary[0] and indexFrom >= boundary[1]) or \ |
566 (lineFrom > self.__selection[0] and lineFrom < self.__selection[2]) or \ |
654 (lineFrom > boundary[0] and lineFrom < boundary[2]) or \ |
567 (lineFrom == self.__selection[2] and indexFrom <= self.__selection[3]): |
655 (lineFrom == boundary[2] and indexFrom <= boundary[3]): |
568 ok = True |
656 ok = True |
569 else: |
657 else: |
570 ok = False |
658 ok = False |
571 aw.selectAll(False) |
659 aw.selectAll(False) |
572 aw.setCursorPosition(cline, cindex) |
660 aw.setCursorPosition(cline, cindex) |