Changeset View
Changeset View
Standalone View
Standalone View
core/textpage.cpp
Show First 20 Lines • Show All 708 Lines • ▼ Show 20 Line(s) | |||||
709 | 709 | | |||
710 | #endif | 710 | #endif | ||
711 | 711 | | |||
712 | return ret; | 712 | return ret; | ||
713 | } | 713 | } | ||
714 | 714 | | |||
715 | 715 | | |||
716 | RegularAreaRect* TextPage::findText( int searchID, const QString &query, SearchDirection direct, | 716 | RegularAreaRect* TextPage::findText( int searchID, const QString &query, SearchDirection direct, | ||
717 | Qt::CaseSensitivity caseSensitivity, const RegularAreaRect *area ) | 717 | Qt::CaseSensitivity caseSensitivity, const RegularAreaRect *area, | ||
718 | const bool wholeWords ) | ||||
718 | { | 719 | { | ||
719 | SearchDirection dir=direct; | 720 | SearchDirection dir=direct; | ||
720 | // invalid search request | 721 | // invalid search request | ||
721 | if ( d->m_words.isEmpty() || query.isEmpty() || ( area && area->isNull() ) ) | 722 | if ( d->m_words.isEmpty() || query.isEmpty() || ( area && area->isNull() ) ) | ||
722 | return nullptr; | 723 | return nullptr; | ||
723 | TextList::ConstIterator start; | 724 | TextList::ConstIterator start; | ||
724 | int start_offset = 0; | 725 | int start_offset = 0; | ||
725 | TextList::ConstIterator end; | 726 | TextList::ConstIterator end; | ||
Show All 33 Lines | 756 | case PreviousResult: | |||
759 | forward = false; | 760 | forward = false; | ||
760 | break; | 761 | break; | ||
761 | }; | 762 | }; | ||
762 | RegularAreaRect* ret = nullptr; | 763 | RegularAreaRect* ret = nullptr; | ||
763 | const TextComparisonFunction cmpFn = caseSensitivity == Qt::CaseSensitive | 764 | const TextComparisonFunction cmpFn = caseSensitivity == Qt::CaseSensitive | ||
764 | ? CaseSensitiveCmpFn : CaseInsensitiveCmpFn; | 765 | ? CaseSensitiveCmpFn : CaseInsensitiveCmpFn; | ||
765 | if ( forward ) | 766 | if ( forward ) | ||
766 | { | 767 | { | ||
767 | ret = d->findTextInternalForward( searchID, query, cmpFn, start, start_offset, end ); | 768 | ret = d->findTextInternalForward( searchID, query, cmpFn, start, start_offset, end, wholeWords ); | ||
768 | } | 769 | } | ||
769 | else | 770 | else | ||
770 | { | 771 | { | ||
771 | ret = d->findTextInternalBackward( searchID, query, cmpFn, start, start_offset, end ); | 772 | ret = d->findTextInternalBackward( searchID, query, cmpFn, start, start_offset, end, wholeWords ); | ||
772 | } | 773 | } | ||
773 | return ret; | 774 | return ret; | ||
774 | } | 775 | } | ||
776 | RegularAreaRect* TextPage::findText( int searchID, const QString &query, SearchDirection direct, | ||||
777 | Qt::CaseSensitivity caseSensitivity, const RegularAreaRect *area ) | ||||
778 | { | ||||
779 | return findText( searchID, query, direct, caseSensitivity, area, false); | ||||
780 | } | ||||
775 | 781 | | |||
776 | // hyphenated '-' must be at the end of a word, so hyphenation means | 782 | // hyphenated '-' must be at the end of a word, so hyphenation means | ||
777 | // we have a '-' just followed by a '\n' character | 783 | // we have a '-' just followed by a '\n' character | ||
778 | // check if the string contains a '-' character | 784 | // check if the string contains a '-' character | ||
779 | // if the '-' is the last entry | 785 | // if the '-' is the last entry | ||
780 | static int stringLengthAdaptedWithHyphen(const QString &str, const TextList::ConstIterator &it, const TextList::ConstIterator &textListEnd) | 786 | static int stringLengthAdaptedWithHyphen(const QString &str, const TextList::ConstIterator &it, const TextList::ConstIterator &textListEnd) | ||
781 | { | 787 | { | ||
782 | int len = str.length(); | 788 | int len = str.length(); | ||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Line(s) | 839 | if (it == sp->it_end) { | |||
834 | break; | 840 | break; | ||
835 | } | 841 | } | ||
836 | } | 842 | } | ||
837 | 843 | | |||
838 | ret->simplify(); | 844 | ret->simplify(); | ||
839 | return ret; | 845 | return ret; | ||
840 | } | 846 | } | ||
841 | 847 | | |||
848 | // Checks if the word searched is whole | ||||
849 | | ||||
850 | bool TextPagePrivate::isWholeWord( const TextList::ConstIterator &start, | ||||
aacid: can this function be marked as const? seems like it could/should | |||||
851 | const TextList::ConstIterator &end) | ||||
852 | { | ||||
853 | | ||||
854 | // Divided in two parts, after the word and before | ||||
855 | bool part1 = false, part2 = false; | ||||
856 | | ||||
857 | // If I'm at the beggining/end of the text, I don't need to check after/before | ||||
yurchor: Typo: beggining -> beginning | |||||
858 | if( start == m_words.constBegin() ) | ||||
aacid: add {} if you're going to have an else with {} | |||||
859 | part1 = true; | ||||
860 | else | ||||
861 | { | ||||
862 | // Else I check if the text before is a number or letter, if it isn't, a word begins here | ||||
863 | TextList::ConstIterator before = start; | ||||
864 | before--; | ||||
865 | const TinyTextEntity* curEntity = *before; | ||||
866 | const QString& str = curEntity->text(); | ||||
867 | int len = stringLengthAdaptedWithHyphen( str, before, m_words.constEnd() ); | ||||
868 | if( !str[len-1].isLetterOrNumber() ) part1 = true; | ||||
869 | } | ||||
870 | | ||||
871 | if( end == m_words.constEnd() ) | ||||
872 | part2 = true; | ||||
873 | else | ||||
874 | { | ||||
875 | | ||||
Make this const aacid: Make this const
Are we sure this is never going to be 0? I had a look at the… | |||||
Only if the tiny text entity is "-\n", I made it to see to make sure. joaonetto: Only if the tiny text entity is "-\n", I made it to see to make sure. | |||||
876 | // For the end is a bit more complicated, some text entities can end at a \n, | ||||
877 | // and checking the next would get the first char in the next phrase. | ||||
878 | // So I'm checking this right here. | ||||
879 | TextList::ConstIterator after = end; | ||||
880 | const TinyTextEntity* endEntity = *after; | ||||
881 | const QString& endStr = endEntity->text(); | ||||
882 | | ||||
883 | if( endStr.endsWith( QStringLiteral("\n") )) | ||||
884 | part2 = true; | ||||
885 | | ||||
886 | // If it doesn't end in \n, I check the next char, as done in before. | ||||
887 | else | ||||
aacid: const | |||||
888 | { | ||||
889 | after++; | ||||
890 | const TinyTextEntity* curEntity = *after; | ||||
891 | const QString& str = curEntity->text(); | ||||
892 | if( !str[0].isLetterOrNumber() ) part2 = true; | ||||
893 | } | ||||
894 | } | ||||
895 | | ||||
896 | return part1 && part2; | ||||
897 | } | ||||
898 | | ||||
842 | RegularAreaRect* TextPagePrivate::findTextInternalForward( int searchID, const QString &_query, | 899 | RegularAreaRect* TextPagePrivate::findTextInternalForward( int searchID, const QString &_query, | ||
843 | TextComparisonFunction comparer, | 900 | TextComparisonFunction comparer, | ||
844 | const TextList::ConstIterator &start, | 901 | const TextList::ConstIterator &start, | ||
845 | int start_offset, | 902 | int start_offset, | ||
846 | const TextList::ConstIterator &end) | 903 | const TextList::ConstIterator &end, | ||
904 | bool wholeWords ) | ||||
847 | { | 905 | { | ||
848 | // normalize query search all unicode (including glyphs) | 906 | // normalize query search all unicode (including glyphs) | ||
849 | const QString query = _query.normalized(QString::NormalizationForm_KC); | 907 | const QString query = _query.normalized(QString::NormalizationForm_KC); | ||
850 | 908 | | |||
851 | // j is the current position in our query | 909 | // j is the current position in our query | ||
852 | // len is the length of the string in TextEntity | 910 | // len is the length of the string in TextEntity | ||
853 | // queryLeft is the length of the query we have left | 911 | // queryLeft is the length of the query we have left | ||
854 | int j=0, queryLeft=query.length(); | 912 | int j=0, queryLeft=query.length(); | ||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Line(s) | |||||
912 | #ifdef DEBUG_TEXTPAGE | 970 | #ifdef DEBUG_TEXTPAGE | ||
913 | qCDebug(OkularCoreDebug) << "\tmatched"; | 971 | qCDebug(OkularCoreDebug) << "\tmatched"; | ||
914 | #endif | 972 | #endif | ||
915 | j += min; | 973 | j += min; | ||
916 | queryLeft -= min; | 974 | queryLeft -= min; | ||
917 | 975 | | |||
918 | if (queryLeft==0) | 976 | if (queryLeft==0) | ||
919 | { | 977 | { | ||
978 | //If it's looking for whole words and this is not a whole word | ||||
979 | if(wholeWords && !isWholeWord(it_begin, it)) | ||||
980 | { | ||||
981 | j = 0; | ||||
982 | queryLeft=query.length(); | ||||
aacid: spaces around = | |||||
983 | it = it_begin; | ||||
984 | offset = offset_begin+1; | ||||
aacid: spaces around + | |||||
985 | it_begin = TextList::ConstIterator(); | ||||
986 | } | ||||
987 | | ||||
988 | else | ||||
989 | { | ||||
920 | // save or update the search point for the current searchID | 990 | // save or update the search point for the current searchID | ||
921 | QMap< int, SearchPoint* >::iterator sIt = m_searchPoints.find( searchID ); | 991 | QMap< int, SearchPoint* >::iterator sIt = m_searchPoints.find( searchID ); | ||
922 | if ( sIt == m_searchPoints.end() ) | 992 | if ( sIt == m_searchPoints.end() ) | ||
923 | { | 993 | { | ||
924 | sIt = m_searchPoints.insert( searchID, new SearchPoint ); | 994 | sIt = m_searchPoints.insert( searchID, new SearchPoint ); | ||
925 | } | 995 | } | ||
926 | SearchPoint* sp = *sIt; | 996 | SearchPoint* sp = *sIt; | ||
927 | sp->it_begin = it_begin; | 997 | sp->it_begin = it_begin; | ||
928 | sp->it_end = it; | 998 | sp->it_end = it; | ||
929 | sp->offset_begin = offset_begin; | 999 | sp->offset_begin = offset_begin; | ||
930 | sp->offset_end = offset + min; | 1000 | sp->offset_end = offset + min; | ||
931 | return searchPointToArea(sp); | 1001 | return searchPointToArea(sp); | ||
932 | } | 1002 | } | ||
933 | 1003 | | |||
1004 | } | ||||
1005 | | ||||
934 | it++; | 1006 | it++; | ||
935 | offset = 0; | 1007 | offset = 0; | ||
936 | } | 1008 | } | ||
937 | } | 1009 | } | ||
938 | } | 1010 | } | ||
939 | // end of loop - it means that we've ended the textentities | 1011 | // end of loop - it means that we've ended the textentities | ||
940 | 1012 | | |||
941 | const QMap< int, SearchPoint* >::iterator sIt = m_searchPoints.find( searchID ); | 1013 | const QMap< int, SearchPoint* >::iterator sIt = m_searchPoints.find( searchID ); | ||
942 | if ( sIt != m_searchPoints.end() ) | 1014 | if ( sIt != m_searchPoints.end() ) | ||
943 | { | 1015 | { | ||
944 | SearchPoint* sp = *sIt; | 1016 | SearchPoint* sp = *sIt; | ||
945 | m_searchPoints.erase( sIt ); | 1017 | m_searchPoints.erase( sIt ); | ||
946 | delete sp; | 1018 | delete sp; | ||
947 | } | 1019 | } | ||
948 | return nullptr; | 1020 | return nullptr; | ||
949 | } | 1021 | } | ||
950 | 1022 | | |||
951 | RegularAreaRect* TextPagePrivate::findTextInternalBackward( int searchID, const QString &_query, | 1023 | RegularAreaRect* TextPagePrivate::findTextInternalForward( int searchID, const QString &_query, | ||
952 | TextComparisonFunction comparer, | 1024 | TextComparisonFunction comparer, | ||
953 | const TextList::ConstIterator &start, | 1025 | const TextList::ConstIterator &start, | ||
954 | int start_offset, | 1026 | int start_offset, | ||
955 | const TextList::ConstIterator &end) | 1027 | const TextList::ConstIterator &end ) | ||
956 | { | 1028 | { | ||
1029 | return findTextInternalForward(searchID, _query, comparer, start, start_offset, end, false); | ||||
1030 | } | ||||
1031 | | ||||
1032 | RegularAreaRect* TextPagePrivate::findTextInternalBackward( int searchID, const QString &_query, | ||||
1033 | TextComparisonFunction comparer, | ||||
1034 | const TextList::ConstIterator &start, | ||||
1035 | int start_offset, | ||||
1036 | const TextList::ConstIterator &end, | ||||
1037 | bool wholeWords ) | ||||
1038 | { | ||||
957 | // normalize query to search all unicode (including glyphs) | 1039 | // normalize query to search all unicode (including glyphs) | ||
958 | const QString query = _query.normalized(QString::NormalizationForm_KC); | 1040 | const QString query = _query.normalized(QString::NormalizationForm_KC); | ||
959 | 1041 | | |||
960 | // j is the current position in our query | 1042 | // j is the current position in our query | ||
961 | // len is the length of the string in TextEntity | 1043 | // len is the length of the string in TextEntity | ||
962 | // queryLeft is the length of the query we have left | 1044 | // queryLeft is the length of the query we have left | ||
963 | int j=query.length(), queryLeft=query.length(); | 1045 | int j=query.length(), queryLeft=query.length(); | ||
964 | 1046 | | |||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Line(s) | |||||
1030 | #ifdef DEBUG_TEXTPAGE | 1112 | #ifdef DEBUG_TEXTPAGE | ||
1031 | qCDebug(OkularCoreDebug) << "\tmatched"; | 1113 | qCDebug(OkularCoreDebug) << "\tmatched"; | ||
1032 | #endif | 1114 | #endif | ||
1033 | j -= min; | 1115 | j -= min; | ||
1034 | queryLeft -= min; | 1116 | queryLeft -= min; | ||
1035 | 1117 | | |||
1036 | if ( queryLeft == 0 ) | 1118 | if ( queryLeft == 0 ) | ||
1037 | { | 1119 | { | ||
1120 | | ||||
1121 | //If it's looking for whole words and this is not a whole word | ||||
1122 | if(wholeWords && !isWholeWord(it, it_begin)) | ||||
1123 | { | ||||
1124 | j = 0; | ||||
1125 | queryLeft=query.length(); | ||||
1126 | it = it_begin; | ||||
1127 | offset = offset_begin+1; | ||||
1128 | it_begin = TextList::ConstIterator(); | ||||
1129 | } | ||||
1130 | else | ||||
1131 | { | ||||
1038 | // save or update the search point for the current searchID | 1132 | // save or update the search point for the current searchID | ||
1039 | QMap< int, SearchPoint* >::iterator sIt = m_searchPoints.find( searchID ); | 1133 | QMap< int, SearchPoint* >::iterator sIt = m_searchPoints.find( searchID ); | ||
1040 | if ( sIt == m_searchPoints.end() ) | 1134 | if ( sIt == m_searchPoints.end() ) | ||
1041 | { | 1135 | { | ||
1042 | sIt = m_searchPoints.insert( searchID, new SearchPoint ); | 1136 | sIt = m_searchPoints.insert( searchID, new SearchPoint ); | ||
1043 | } | 1137 | } | ||
1044 | SearchPoint* sp = *sIt; | 1138 | SearchPoint* sp = *sIt; | ||
1045 | sp->it_begin = it; | 1139 | sp->it_begin = it; | ||
1046 | sp->it_end = it_begin; | 1140 | sp->it_end = it_begin; | ||
1047 | sp->offset_begin = offset - min; | 1141 | sp->offset_begin = offset - min; | ||
1048 | sp->offset_end = offset_begin; | 1142 | sp->offset_end = offset_begin; | ||
1049 | return searchPointToArea(sp); | 1143 | return searchPointToArea(sp); | ||
1050 | } | 1144 | } | ||
1145 | } | ||||
1051 | 1146 | | |||
1052 | offset = 0; | 1147 | offset = 0; | ||
1053 | } | 1148 | } | ||
1054 | 1149 | | |||
1055 | } | 1150 | } | ||
1056 | 1151 | | |||
1057 | } | 1152 | } | ||
1058 | // end of loop - it means that we've ended the textentities | 1153 | // end of loop - it means that we've ended the textentities | ||
1059 | 1154 | | |||
1060 | const QMap< int, SearchPoint* >::iterator sIt = m_searchPoints.find( searchID ); | 1155 | const QMap< int, SearchPoint* >::iterator sIt = m_searchPoints.find( searchID ); | ||
1061 | if ( sIt != m_searchPoints.end() ) | 1156 | if ( sIt != m_searchPoints.end() ) | ||
1062 | { | 1157 | { | ||
1063 | SearchPoint* sp = *sIt; | 1158 | SearchPoint* sp = *sIt; | ||
1064 | m_searchPoints.erase( sIt ); | 1159 | m_searchPoints.erase( sIt ); | ||
1065 | delete sp; | 1160 | delete sp; | ||
1066 | } | 1161 | } | ||
1067 | return nullptr; | 1162 | return nullptr; | ||
1068 | } | 1163 | } | ||
1069 | 1164 | | |||
1165 | RegularAreaRect * TextPagePrivate::findTextInternalBackward( int searchID, const QString &_query, | ||||
1166 | TextComparisonFunction comparer, | ||||
1167 | const TextList::ConstIterator &start, | ||||
1168 | int start_offset, | ||||
1169 | const TextList::ConstIterator &end ) | ||||
1170 | { | ||||
1171 | return findTextInternalBackward( searchID, _query, comparer, start, start_offset, end, false ); | ||||
1172 | } | ||||
1173 | | ||||
1070 | QString TextPage::text(const RegularAreaRect *area) const | 1174 | QString TextPage::text(const RegularAreaRect *area) const | ||
1071 | { | 1175 | { | ||
1072 | return text(area, AnyPixelTextAreaInclusionBehaviour); | 1176 | return text(area, AnyPixelTextAreaInclusionBehaviour); | ||
1073 | } | 1177 | } | ||
1074 | 1178 | | |||
1075 | QString TextPage::text(const RegularAreaRect *area, TextAreaInclusionBehaviour b) const | 1179 | QString TextPage::text(const RegularAreaRect *area, TextAreaInclusionBehaviour b) const | ||
1076 | { | 1180 | { | ||
1077 | if ( area && area->isNull() ) | 1181 | if ( area && area->isNull() ) | ||
▲ Show 20 Lines • Show All 961 Lines • Show Last 20 Lines |
can this function be marked as const? seems like it could/should