aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <dmoagx@users.noreply.github.com>2018-05-08 01:59:50 +0200
committerMax <dmoagx@users.noreply.github.com>2018-05-08 01:59:50 +0200
commit1838bb50da412fc3875aeb95ab082a9721000efc (patch)
treec8f924a4affb67181bc25eaf9e35be1d0ae8a37c
parentd463f555748c9010ab7b570851b8648fa9e117a8 (diff)
downloadsequelpro-1838bb50da412fc3875aeb95ab082a9721000efc.tar.gz
sequelpro-1838bb50da412fc3875aeb95ab082a9721000efc.tar.bz2
sequelpro-1838bb50da412fc3875aeb95ab082a9721000efc.zip
Move advanced filter table code into its own class + xib
-rw-r--r--Interfaces/English.lproj/DBView.xib318
-rw-r--r--Interfaces/English.lproj/FilterTableWindow.xib337
-rw-r--r--Source/SPFilterTableController.h129
-rw-r--r--Source/SPFilterTableController.m698
-rw-r--r--Source/SPHistoryController.m2
-rw-r--r--Source/SPTableContent.h34
-rw-r--r--Source/SPTableContent.m877
-rw-r--r--sequel-pro.xcodeproj/project.pbxproj18
8 files changed, 1352 insertions, 1061 deletions
diff --git a/Interfaces/English.lproj/DBView.xib b/Interfaces/English.lproj/DBView.xib
index 042c1381..a725d186 100644
--- a/Interfaces/English.lproj/DBView.xib
+++ b/Interfaces/English.lproj/DBView.xib
@@ -4187,310 +4187,6 @@ Gw
<outlet property="initialFirstResponder" destination="5452" id="5525"/>
</connections>
</window>
- <window title="Advanced Filter" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hidesOnDeactivate="YES" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="SPTableFilterPanel" animationBehavior="default" id="8068" userLabel="Advanced Filter Table Window" customClass="NSPanel">
- <windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES" nonactivatingPanel="YES"/>
- <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
- <rect key="contentRect" x="162" y="162" width="752" height="317"/>
- <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1178"/>
- <value key="minSize" type="size" width="600" height="317"/>
- <view key="contentView" id="8069" userLabel="Filter Table Window">
- <rect key="frame" x="0.0" y="0.0" width="752" height="317"/>
- <autoresizingMask key="autoresizingMask"/>
- <subviews>
- <splitView dividerStyle="thin" id="8079" customClass="SPSplitView">
- <rect key="frame" x="0.0" y="40" width="752" height="277"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <subviews>
- <customView id="8080">
- <rect key="frame" x="0.0" y="0.0" width="752" height="141"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <subviews>
- <scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="8141">
- <rect key="frame" x="0.0" y="0.0" width="752" height="142"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <clipView key="contentView" id="e9P-dP-cyb">
- <rect key="frame" x="0.0" y="0.0" width="752" height="142"/>
- <autoresizingMask key="autoresizingMask"/>
- <subviews>
- <tableView identifier="AdvancedFilterTableView" verticalHuggingPriority="750" allowsExpansionToolTips="YES" selectionHighlightStyle="sourceList" alternatingRowBackgroundColors="YES" emptySelection="NO" autosaveColumns="NO" headerView="8145" id="8144" customClass="SPCopyTable">
- <rect key="frame" x="0.0" y="0.0" width="752" height="125"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <size key="intercellSpacing" width="3" height="2"/>
- <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
- <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
- <tableColumns>
- <tableColumn width="748.921875" minWidth="40" maxWidth="1000" id="8146">
- <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
- <font key="font" metaFont="smallSystem"/>
- <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
- </tableHeaderCell>
- <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="8149">
- <font key="font" metaFont="system"/>
- <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
- </textFieldCell>
- <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
- </tableColumn>
- </tableColumns>
- <connections>
- <outlet property="dataSource" destination="67" id="8157"/>
- <outlet property="delegate" destination="67" id="8158"/>
- </connections>
- </tableView>
- </subviews>
- </clipView>
- <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="8143">
- <rect key="frame" x="1" y="95.851600000000005" width="751.5" height="15"/>
- <autoresizingMask key="autoresizingMask"/>
- </scroller>
- <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="8142">
- <rect key="frame" x="224" y="17" width="15" height="102"/>
- <autoresizingMask key="autoresizingMask"/>
- </scroller>
- <tableHeaderView key="headerView" id="8145">
- <rect key="frame" x="0.0" y="0.0" width="752" height="17"/>
- <autoresizingMask key="autoresizingMask"/>
- </tableHeaderView>
- </scrollView>
- </subviews>
- </customView>
- <customView id="8081">
- <rect key="frame" x="0.0" y="142" width="752" height="135"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <subviews>
- <button toolTip="Perform filter while typing (⌘T)" id="8129">
- <rect key="frame" x="537" y="97" width="197" height="18"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
- <buttonCell key="cell" type="check" title="Search while typing" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="8130">
- <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
- <font key="font" metaFont="smallSystem"/>
- <string key="keyEquivalent">t</string>
- <modifierMask key="keyEquivalentModifierMask" command="YES"/>
- </buttonCell>
- </button>
- <button toolTip="If set negate entire WHERE clause (⌘N)" id="8131">
- <rect key="frame" x="537" y="77" width="197" height="18"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
- <buttonCell key="cell" type="check" title="Negate clause" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="8132">
- <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
- <font key="font" metaFont="smallSystem"/>
- <string key="keyEquivalent">n</string>
- <modifierMask key="keyEquivalentModifierMask" command="YES"/>
- </buttonCell>
- <connections>
- <action selector="toggleNegateClause:" target="67" id="8172"/>
- </connections>
- </button>
- <button toolTip="Perform filtering by using SELECT DISTINCT" id="8133">
- <rect key="frame" x="537" y="57" width="197" height="18"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
- <buttonCell key="cell" type="check" title="Select distinct" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="8134">
- <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
- <font key="font" metaFont="smallSystem"/>
- <string key="keyEquivalent">d</string>
- <modifierMask key="keyEquivalentModifierMask" command="YES"/>
- </buttonCell>
- <connections>
- <action selector="toggleDistinctSelect:" target="67" id="8170"/>
- </connections>
- </button>
- <textField verticalHuggingPriority="750" id="8135">
- <rect key="frame" x="537" y="37" width="137" height="14"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
- <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Default operator:" id="8136">
- <font key="font" metaFont="smallSystem"/>
- <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
- </textFieldCell>
- </textField>
- <button toolTip="Set default operator which should be used if pattern doen't begin with an operator" verticalHuggingPriority="750" id="8137">
- <rect key="frame" x="678" y="35" width="55" height="16"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
- <buttonCell key="cell" type="push" title="Edit" bezelStyle="rounded" alignment="center" controlSize="mini" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8138">
- <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
- <font key="font" metaFont="miniSystem"/>
- <string key="keyEquivalent">o</string>
- <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
- </buttonCell>
- <connections>
- <action selector="setDefaultOperator:" target="67" id="8163"/>
- </connections>
- </button>
- <textField verticalHuggingPriority="750" id="8139">
- <rect key="frame" x="554" y="19" width="181" height="14"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
- <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="LIKE '%@%'" id="8140">
- <font key="font" metaFont="smallSystem"/>
- <color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
- </textFieldCell>
- <connections>
- <binding destination="1907" name="value" keyPath="values.FilterTableDefaultOperator" id="8167"/>
- </connections>
- </textField>
- <textField verticalHuggingPriority="750" id="8180">
- <rect key="frame" x="17" y="115" width="294" height="14"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
- <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="WHERE query" id="8181">
- <font key="font" metaFont="smallSystem"/>
- <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
- </textFieldCell>
- </textField>
- <scrollView autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="8204">
- <rect key="frame" x="20" y="21" width="512" height="92"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <clipView key="contentView" copiesOnScroll="NO" id="FLj-pH-h40">
- <rect key="frame" x="1" y="1" width="510" height="90"/>
- <autoresizingMask key="autoresizingMask"/>
- <subviews>
- <textView editable="NO" importsGraphics="NO" findStyle="panel" allowsNonContiguousLayout="YES" id="8207" customClass="SPTextView">
- <rect key="frame" x="0.0" y="0.0" width="510" height="90"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
- <size key="minSize" width="510" height="90"/>
- <size key="maxSize" width="518" height="10000000"/>
- <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
- <connections>
- <outlet property="delegate" destination="67" id="8208"/>
- </connections>
- </textView>
- </subviews>
- </clipView>
- <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="8206">
- <rect key="frame" x="1" y="119" width="232" height="15"/>
- <autoresizingMask key="autoresizingMask"/>
- </scroller>
- <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="8205">
- <rect key="frame" x="224" y="1" width="15" height="127"/>
- <autoresizingMask key="autoresizingMask"/>
- </scroller>
- </scrollView>
- </subviews>
- </customView>
- </subviews>
- <holdingPriorities>
- <real value="250"/>
- <real value="250"/>
- </holdingPriorities>
- </splitView>
- <button toolTip="Apply Filter to current Table (⌘F)" verticalHuggingPriority="750" id="8083">
- <rect key="frame" x="595" y="12" width="143" height="32"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
- <buttonCell key="cell" type="push" title="Filter" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8084">
- <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
- <font key="font" metaFont="system"/>
- <string key="keyEquivalent">f</string>
- <modifierMask key="keyEquivalentModifierMask" command="YES"/>
- </buttonCell>
- <connections>
- <action selector="filterTable:" target="67" id="8176"/>
- </connections>
- </button>
- <button toolTip="Create a WHERE clause to search for the last typed pattern in all fields" verticalHuggingPriority="750" id="8127">
- <rect key="frame" x="14" y="12" width="216" height="32"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <buttonCell key="cell" type="push" title="Search all fields" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8128">
- <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
- <font key="font" metaFont="system"/>
- <string key="keyEquivalent">a</string>
- <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
- </buttonCell>
- <connections>
- <action selector="toggleLookAllFieldsMode:" target="67" id="8168"/>
- </connections>
- </button>
- <button toolTip="Clear all Filter Criterias (⌘⌫)" verticalHuggingPriority="750" id="8085">
- <rect key="frame" x="452" y="12" width="143" height="32"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
- <buttonCell key="cell" type="push" title="Clear" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8086">
- <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
- <font key="font" metaFont="system"/>
- <string key="keyEquivalent"></string>
- <modifierMask key="keyEquivalentModifierMask" command="YES"/>
- </buttonCell>
- <connections>
- <action selector="tableFilterClear:" target="67" id="8175"/>
- </connections>
- </button>
- </subviews>
- </view>
- <connections>
- <outlet property="initialFirstResponder" destination="8144" id="8159"/>
- </connections>
- </window>
- <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="7609" userLabel="Filter Table Set Default Operator Sheet" customClass="NSPanel">
- <windowStyleMask key="styleMask" titled="YES"/>
- <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
- <rect key="contentRect" x="235" y="418" width="251" height="102"/>
- <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1178"/>
- <value key="minSize" type="size" width="251" height="102"/>
- <value key="maxSize" type="size" width="251" height="102"/>
- <view key="contentView" id="7610">
- <rect key="frame" x="0.0" y="0.0" width="251" height="102"/>
- <autoresizingMask key="autoresizingMask"/>
- <subviews>
- <button verticalHuggingPriority="750" tag="1" id="7615">
- <rect key="frame" x="140" y="13" width="96" height="28"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
- <buttonCell key="cell" type="push" title="Save" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="7616">
- <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
- <font key="font" metaFont="smallSystem"/>
- <string key="keyEquivalent" base64-UTF8="YES">
-DQ
-</string>
- </buttonCell>
- <connections>
- <action selector="closeSheet:" target="67" id="7627"/>
- </connections>
- </button>
- <button verticalHuggingPriority="750" id="7617">
- <rect key="frame" x="46" y="13" width="96" height="28"/>
- <autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
- <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="7618">
- <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
- <font key="font" metaFont="smallSystem"/>
- <string key="keyEquivalent" base64-UTF8="YES">
-Gw
-</string>
- </buttonCell>
- <connections>
- <action selector="closeSheet:" target="67" id="7628"/>
- </connections>
- </button>
- <textField verticalHuggingPriority="750" id="7619">
- <rect key="frame" x="17" y="76" width="208" height="14"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
- <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Enter Filter Table's Default Operator:" id="7620">
- <font key="font" metaFont="smallSystem"/>
- <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
- </textFieldCell>
- </textField>
- <comboBox verticalHuggingPriority="750" id="7629">
- <rect key="frame" x="20" y="51" width="214" height="22"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
- <comboBoxCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="7630">
- <font key="font" metaFont="smallSystem"/>
- <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
- <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
- </comboBoxCell>
- </comboBox>
- <button horizontalHuggingPriority="750" verticalHuggingPriority="750" id="7814">
- <rect key="frame" x="17" y="14" width="25" height="25"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <buttonCell key="cell" type="help" bezelStyle="helpButton" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="7815">
- <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
- <font key="font" metaFont="smallSystem"/>
- </buttonCell>
- <connections>
- <action selector="showDefaultOperaterHelp:" target="67" id="7816"/>
- </connections>
- </button>
- </subviews>
- </view>
- </window>
<window title="Query Favorite Sheet" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="6405" userLabel="Query Favorite Sheet" customClass="NSPanel">
<windowStyleMask key="styleMask" titled="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
@@ -4903,18 +4599,7 @@ Gw
<outlet property="filterButton" destination="4676" id="5942"/>
<outlet property="filterControllerInstance" destination="ki9-Po-bdr" id="5od-0U-9xj"/>
<outlet property="filterRuleEditorContainer" destination="9oo-u0-ndW" id="OZb-jI-CMy"/>
- <outlet property="filterTableDistinctCheckbox" destination="8133" id="8171"/>
- <outlet property="filterTableFilterButton" destination="8083" id="8177"/>
- <outlet property="filterTableLiveSearchCheckbox" destination="8129" id="8174"/>
- <outlet property="filterTableNegateCheckbox" destination="8131" id="8173"/>
- <outlet property="filterTableQueryTitle" destination="8180" id="8184"/>
- <outlet property="filterTableSearchAllFields" destination="8127" id="8169"/>
- <outlet property="filterTableSetDefaultOperatorSheet" destination="7609" id="7632"/>
- <outlet property="filterTableSetDefaultOperatorValue" destination="7629" id="7631"/>
- <outlet property="filterTableSplitView" destination="8079" id="8178"/>
- <outlet property="filterTableView" destination="8144" id="8160"/>
- <outlet property="filterTableWhereClause" destination="8207" id="8209"/>
- <outlet property="filterTableWindow" destination="8068" id="8161"/>
+ <outlet property="filterTableController" destination="UBS-cN-3Af" id="FV7-by-Gy1"/>
<outlet property="multipleLineEditingButton" destination="5201" id="5203"/>
<outlet property="paginationButton" destination="6653" id="6657"/>
<outlet property="paginationNextButton" destination="6647" id="6664"/>
@@ -4941,6 +4626,7 @@ Gw
<outlet property="tablesListInstance" destination="68" id="byh-Eh-UAv"/>
</connections>
</customObject>
+ <customObject id="UBS-cN-3Af" customClass="SPFilterTableController"/>
<customObject id="362" userLabel="TableDump" customClass="SPDataImport">
<connections>
<outlet property="customQueryInstance" destination="134" id="953"/>
diff --git a/Interfaces/English.lproj/FilterTableWindow.xib b/Interfaces/English.lproj/FilterTableWindow.xib
new file mode 100644
index 00000000..79da4153
--- /dev/null
+++ b/Interfaces/English.lproj/FilterTableWindow.xib
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
+ <dependencies>
+ <deployment identifier="macosx"/>
+ <development version="8000" identifier="xcode"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14109"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <objects>
+ <customObject id="-2" userLabel="File's Owner" customClass="SPFilterTableController">
+ <connections>
+ <outlet property="filterTableClearButton" destination="egJ-46-zsK" id="Fq2-LD-h16"/>
+ <outlet property="filterTableDistinctCheckbox" destination="kkn-vg-a1j" id="TDf-pu-HAk"/>
+ <outlet property="filterTableFilterButton" destination="97a-9g-t3j" id="zGX-CX-g2a"/>
+ <outlet property="filterTableLiveSearchCheckbox" destination="eW4-hf-ige" id="PR5-mS-LUC"/>
+ <outlet property="filterTableNegateCheckbox" destination="hdW-5X-UDu" id="NRU-CX-c0O"/>
+ <outlet property="filterTableQueryTitle" destination="WnE-kO-RxG" id="sVM-Sr-Er2"/>
+ <outlet property="filterTableSearchAllFields" destination="dCH-wr-KbJ" id="9xp-Cs-5GB"/>
+ <outlet property="filterTableSetDefaultOperatorSheet" destination="bXg-MQ-c5g" id="Ph2-a6-R2H"/>
+ <outlet property="filterTableSetDefaultOperatorValue" destination="KZQ-WN-rtU" id="QzL-fH-WTe"/>
+ <outlet property="filterTableSplitView" destination="Xk5-iI-QZb" id="Bv6-90-fDH"/>
+ <outlet property="filterTableView" destination="8SC-Fh-D9L" id="nIF-tg-501"/>
+ <outlet property="filterTableWhereClause" destination="NLm-8l-MrV" id="hMK-Jf-ydK"/>
+ <outlet property="window" destination="nzu-CY-UY7" id="EAC-V1-Oqh"/>
+ </connections>
+ </customObject>
+ <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+ <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+ <window title="Advanced Filter" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hidesOnDeactivate="YES" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="SPTableFilterPanel" animationBehavior="default" id="nzu-CY-UY7" userLabel="Advanced Filter Table Window" customClass="NSPanel">
+ <windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES" nonactivatingPanel="YES"/>
+ <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+ <rect key="contentRect" x="162" y="162" width="752" height="317"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1057"/>
+ <value key="minSize" type="size" width="600" height="317"/>
+ <view key="contentView" id="mgs-0s-XcR" userLabel="Filter Table Window">
+ <rect key="frame" x="0.0" y="0.0" width="752" height="317"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <splitView dividerStyle="thin" id="Xk5-iI-QZb" customClass="SPSplitView">
+ <rect key="frame" x="0.0" y="40" width="752" height="277"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <customView id="P9T-cb-A1O">
+ <rect key="frame" x="0.0" y="0.0" width="752" height="141"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="Zmg-mY-I5z">
+ <rect key="frame" x="0.0" y="0.0" width="752" height="142"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <clipView key="contentView" id="PO1-a7-WBE">
+ <rect key="frame" x="0.0" y="23" width="752" height="119"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <tableView identifier="AdvancedFilterTableView" verticalHuggingPriority="750" allowsExpansionToolTips="YES" selectionHighlightStyle="sourceList" alternatingRowBackgroundColors="YES" emptySelection="NO" autosaveColumns="NO" headerView="eWi-Z3-2Sr" id="8SC-Fh-D9L" customClass="SPCopyTable">
+ <rect key="frame" x="0.0" y="0.0" width="752" height="119"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <size key="intercellSpacing" width="3" height="2"/>
+ <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+ <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
+ <tableColumns>
+ <tableColumn identifier="" width="748.921875" minWidth="40" maxWidth="1000" id="VGf-vY-BT6">
+ <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
+ </tableHeaderCell>
+ <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="isR-QM-Zos">
+ <font key="font" metaFont="system"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+ </tableColumn>
+ </tableColumns>
+ <connections>
+ <outlet property="dataSource" destination="-2" id="dtT-f4-3yI"/>
+ <outlet property="delegate" destination="-2" id="hvw-73-bmw"/>
+ </connections>
+ </tableView>
+ </subviews>
+ </clipView>
+ <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="E65-Wo-BZ0">
+ <rect key="frame" x="1" y="95.851600000000005" width="751.5" height="15"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </scroller>
+ <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="Vnq-gG-GNh">
+ <rect key="frame" x="224" y="17" width="15" height="102"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </scroller>
+ <tableHeaderView key="headerView" id="eWi-Z3-2Sr">
+ <rect key="frame" x="0.0" y="0.0" width="752" height="23"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </tableHeaderView>
+ </scrollView>
+ </subviews>
+ </customView>
+ <customView id="86d-uH-suk">
+ <rect key="frame" x="0.0" y="142" width="752" height="135"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <button toolTip="Perform filter while typing (⌘T)" id="eW4-hf-ige">
+ <rect key="frame" x="537" y="97" width="197" height="18"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+ <buttonCell key="cell" type="check" title="Search while typing" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="XTP-ut-VQL">
+ <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <string key="keyEquivalent">t</string>
+ <modifierMask key="keyEquivalentModifierMask" command="YES"/>
+ </buttonCell>
+ </button>
+ <button toolTip="If set negate entire WHERE clause (⌘N)" id="hdW-5X-UDu">
+ <rect key="frame" x="537" y="77" width="197" height="18"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+ <buttonCell key="cell" type="check" title="Negate clause" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="F8k-g6-s93">
+ <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <string key="keyEquivalent">n</string>
+ <modifierMask key="keyEquivalentModifierMask" command="YES"/>
+ </buttonCell>
+ <connections>
+ <action selector="toggleNegateClause:" target="-2" id="leY-aP-oLa"/>
+ </connections>
+ </button>
+ <button toolTip="Perform filtering by using SELECT DISTINCT" id="kkn-vg-a1j">
+ <rect key="frame" x="537" y="57" width="197" height="18"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+ <buttonCell key="cell" type="check" title="Select distinct" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="n3P-Lk-0tv">
+ <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <string key="keyEquivalent">d</string>
+ <modifierMask key="keyEquivalentModifierMask" command="YES"/>
+ </buttonCell>
+ <connections>
+ <action selector="toggleDistinctSelect:" target="-2" id="8jm-si-8p2"/>
+ </connections>
+ </button>
+ <textField verticalHuggingPriority="750" id="Lir-gD-3FT">
+ <rect key="frame" x="537" y="37" width="137" height="14"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Default operator:" id="fOH-Fz-FbJ">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <button toolTip="Set default operator which should be used if pattern doen't begin with an operator" verticalHuggingPriority="750" id="AnE-dT-3rB">
+ <rect key="frame" x="678" y="35" width="55" height="16"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+ <buttonCell key="cell" type="push" title="Edit" bezelStyle="rounded" alignment="center" controlSize="mini" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="XWS-uW-aVd">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="miniSystem"/>
+ <string key="keyEquivalent">o</string>
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ </buttonCell>
+ <connections>
+ <action selector="setDefaultOperator:" target="-2" id="4EO-rc-z56"/>
+ </connections>
+ </button>
+ <textField verticalHuggingPriority="750" id="eRx-Pl-FwB">
+ <rect key="frame" x="554" y="19" width="181" height="14"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="LIKE '%@%'" id="Hag-Ug-A4W">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ <connections>
+ <binding destination="E5e-Af-qLe" name="value" keyPath="values.FilterTableDefaultOperator" id="snR-X9-Dad"/>
+ </connections>
+ </textField>
+ <textField verticalHuggingPriority="750" id="WnE-kO-RxG">
+ <rect key="frame" x="17" y="115" width="294" height="14"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="WHERE query" id="iRJ-gQ-rJy">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <scrollView autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="xjR-JS-f3q">
+ <rect key="frame" x="20" y="21" width="512" height="92"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <clipView key="contentView" copiesOnScroll="NO" id="TBT-Nn-Rpn">
+ <rect key="frame" x="1" y="1" width="510" height="90"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <subviews>
+ <textView editable="NO" importsGraphics="NO" verticallyResizable="NO" findStyle="panel" allowsNonContiguousLayout="YES" id="NLm-8l-MrV" customClass="SPTextView">
+ <rect key="frame" x="0.0" y="0.0" width="510" height="90"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <size key="minSize" width="510" height="90"/>
+ <size key="maxSize" width="518" height="10000000"/>
+ <color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <connections>
+ <outlet property="delegate" destination="-2" id="nM8-08-2Rj"/>
+ </connections>
+ </textView>
+ </subviews>
+ </clipView>
+ <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="dpu-5p-anM">
+ <rect key="frame" x="1" y="119" width="232" height="15"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </scroller>
+ <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="vhd-6q-xMy">
+ <rect key="frame" x="224" y="1" width="15" height="127"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </scroller>
+ </scrollView>
+ </subviews>
+ </customView>
+ </subviews>
+ <holdingPriorities>
+ <real value="250"/>
+ <real value="250"/>
+ </holdingPriorities>
+ </splitView>
+ <button toolTip="Apply Filter to current Table (⌘F)" verticalHuggingPriority="750" id="97a-9g-t3j">
+ <rect key="frame" x="595" y="12" width="143" height="32"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+ <buttonCell key="cell" type="push" title="Filter" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="aso-eo-Uh0">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="system"/>
+ <string key="keyEquivalent">f</string>
+ <modifierMask key="keyEquivalentModifierMask" command="YES"/>
+ </buttonCell>
+ <connections>
+ <action selector="filterTable:" target="-2" id="RuC-c5-aMP"/>
+ </connections>
+ </button>
+ <button toolTip="Create a WHERE clause to search for the last typed pattern in all fields" verticalHuggingPriority="750" id="dCH-wr-KbJ">
+ <rect key="frame" x="14" y="12" width="216" height="32"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <buttonCell key="cell" type="push" title="Search all fields" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Ojj-hI-KbP">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="system"/>
+ <string key="keyEquivalent">a</string>
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ </buttonCell>
+ <connections>
+ <action selector="toggleLookAllFieldsMode:" target="-2" id="S7l-Cy-VFb"/>
+ </connections>
+ </button>
+ <button toolTip="Clear all Filter Criterias (⌘⌫)" verticalHuggingPriority="750" id="egJ-46-zsK">
+ <rect key="frame" x="452" y="12" width="143" height="32"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+ <buttonCell key="cell" type="push" title="Clear" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="0Ec-f2-4N5">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="system"/>
+ <string key="keyEquivalent"></string>
+ <modifierMask key="keyEquivalentModifierMask" command="YES"/>
+ </buttonCell>
+ <connections>
+ <action selector="tableFilterClear:" target="-2" id="f00-8N-Gks"/>
+ </connections>
+ </button>
+ </subviews>
+ </view>
+ <connections>
+ <outlet property="initialFirstResponder" destination="8SC-Fh-D9L" id="zBz-CD-uGL"/>
+ </connections>
+ <point key="canvasLocation" x="146" y="493"/>
+ </window>
+ <userDefaultsController representsSharedInstance="YES" id="E5e-Af-qLe"/>
+ <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="bXg-MQ-c5g" userLabel="Filter Table Set Default Operator Sheet" customClass="NSPanel">
+ <windowStyleMask key="styleMask" titled="YES"/>
+ <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+ <rect key="contentRect" x="235" y="418" width="251" height="102"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1057"/>
+ <value key="minSize" type="size" width="251" height="102"/>
+ <value key="maxSize" type="size" width="251" height="102"/>
+ <view key="contentView" id="nxt-IK-Ukn">
+ <rect key="frame" x="0.0" y="0.0" width="251" height="102"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <button verticalHuggingPriority="750" tag="1" id="dzK-Nw-kVd">
+ <rect key="frame" x="140" y="13" width="96" height="28"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+ <buttonCell key="cell" type="push" title="Save" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="lvs-yx-6iE">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <string key="keyEquivalent" base64-UTF8="YES">
+DQ
+</string>
+ </buttonCell>
+ <connections>
+ <action selector="closeSheet:" target="-2" id="Szi-4E-jOM"/>
+ </connections>
+ </button>
+ <button verticalHuggingPriority="750" id="eKg-Fu-UA7">
+ <rect key="frame" x="46" y="13" width="96" height="28"/>
+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
+ <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="FJo-lE-2oi">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ <string key="keyEquivalent" base64-UTF8="YES">
+Gw
+</string>
+ </buttonCell>
+ <connections>
+ <action selector="closeSheet:" target="-2" id="HtZ-Ia-92w"/>
+ </connections>
+ </button>
+ <textField verticalHuggingPriority="750" id="iLi-Fh-ovo">
+ <rect key="frame" x="17" y="76" width="208" height="14"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+ <textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Enter Filter Table's Default Operator:" id="Aps-Nn-GvU">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+ </textFieldCell>
+ </textField>
+ <comboBox verticalHuggingPriority="750" id="KZQ-WN-rtU">
+ <rect key="frame" x="20" y="51" width="214" height="22"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+ <comboBoxCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="UeY-Ej-YPK">
+ <font key="font" metaFont="smallSystem"/>
+ <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+ </comboBoxCell>
+ </comboBox>
+ <button horizontalHuggingPriority="750" verticalHuggingPriority="750" id="6wf-fR-6SB">
+ <rect key="frame" x="17" y="14" width="25" height="25"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <buttonCell key="cell" type="help" bezelStyle="helpButton" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="QYZ-U7-zc5">
+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+ <font key="font" metaFont="smallSystem"/>
+ </buttonCell>
+ <connections>
+ <action selector="showDefaultOperaterHelp:" target="-2" id="hCi-Lg-QN3"/>
+ </connections>
+ </button>
+ </subviews>
+ </view>
+ <point key="canvasLocation" x="75" y="132"/>
+ </window>
+ </objects>
+</document>
diff --git a/Source/SPFilterTableController.h b/Source/SPFilterTableController.h
new file mode 100644
index 00000000..7bf02593
--- /dev/null
+++ b/Source/SPFilterTableController.h
@@ -0,0 +1,129 @@
+//
+// SPFilterTableController.h
+// sequel-pro
+//
+// Created by Max Lohrmann on 07.05.18.
+// Copyright (c) 2018 Max Lohrmann. All rights reserved.
+// Relocated from existing files. Previous copyright applies.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// More info at <https://github.com/sequelpro/sequelpro>
+
+@class SPSplitView;
+@class SPCopyTable;
+@class SPTextView;
+
+@interface SPFilterTableController : NSWindowController
+{
+ IBOutlet SPSplitView *filterTableSplitView;
+ IBOutlet NSButton *filterTableFilterButton;
+ IBOutlet NSButton *filterTableClearButton;
+ IBOutlet NSButton *filterTableSearchAllFields;
+
+ IBOutlet SPCopyTable *filterTableView;
+
+ IBOutlet NSButton *filterTableLiveSearchCheckbox;
+ IBOutlet NSButton *filterTableNegateCheckbox;
+ IBOutlet NSButton *filterTableDistinctCheckbox;
+
+ IBOutlet NSTextField *filterTableQueryTitle;
+ IBOutlet SPTextView *filterTableWhereClause;
+
+ IBOutlet NSPanel *filterTableSetDefaultOperatorSheet;
+ IBOutlet NSComboBox* filterTableSetDefaultOperatorValue;
+
+ NSUserDefaults *prefs;
+
+ NSMutableDictionary *filterTableData;
+ BOOL filterTableNegate;
+ BOOL filterTableDistinct;
+ BOOL filterTableIsSwapped;
+ NSString *filterTableDefaultOperator;
+ NSString *lastEditedFilterTableValue;
+
+ id target;
+ SEL action;
+}
+
+/**
+ * Puts the filter table window on screen
+ *
+ * MUST BE CALLED ON THE UI THREAD!
+ */
+- (void)showFilterTableWindow;
+
+/**
+ * Restores filter table content state from serialized data
+ *
+ * MUST BE CALLED ON THE UI THREAD!
+ */
+- (void)setFilterTableData:(NSData *)arcData;
+
+/**
+ * Returns the current contents of the filter table window as serialized data
+ *
+ * MUST BE CALLED ON THE UI THREAD!
+ */
+- (NSData *)filterTableData;
+
+/**
+ * The SQL expression to use as filter.
+ * Can be nil if no filter is set!
+ *
+ * MUST BE CALLED ON THE UI THREAD!
+ */
+- (NSString *)tableFilterString;
+
+/**
+ * Will reconfigure the columns of the filter table view from the given array.
+ * Call with nil to reset the table view to its initial empty state.
+ *
+ * MUST BE CALLED ON THE UI THREAD!
+ */
+- (void)setColumns:(NSArray *)dataColumns;
+
+/**
+ * Will return YES if the SQL expression returned by -tableFilterString should be
+ * used in a "SELECT DISTINCT …" query.
+ *
+ * Results may be inconsistent if not called on the main thread!
+ */
+- (BOOL)isDistinct;
+
+/**
+ * Use this method to make the filter window indicate an error state after executing the filter.
+ * Pass 0 for error ID to indicate an OK state.
+ *
+ * MUST BE CALLED ON THE UI THREAD!
+ */
+- (void)setFilterError:(NSUInteger)errorID message:(NSString *)message sqlstate:(NSString *)sqlstate;
+
+/**
+ * Used when the filter table window wants to trigger filtering
+ *
+ * Results may be inconsistent if not called on the main thread!
+ */
+@property (assign, nonatomic) id target;
+@property (assign, nonatomic) SEL action;
+
+@end
diff --git a/Source/SPFilterTableController.m b/Source/SPFilterTableController.m
new file mode 100644
index 00000000..dc1bf98a
--- /dev/null
+++ b/Source/SPFilterTableController.m
@@ -0,0 +1,698 @@
+//
+// SPFilterTableController.m
+// sequel-pro
+//
+// Created by Max Lohrmann on 07.05.18.
+// Copyright (c) 2018 Max Lohrmann. All rights reserved.
+// Relocated from existing files. Previous copyright applies.
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// More info at <https://github.com/sequelpro/sequelpro>
+
+#import "SPFilterTableController.h"
+#import "SPSplitView.h"
+#import "SPCopyTable.h"
+#import "SPTextView.h"
+#import "RegexKitLite.h"
+#import "SPTextAndLinkCell.h"
+
+static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOperator";
+static void *FilterTableKVOContext = &FilterTableKVOContext;
+
+@interface SPFilterTableController () <NSTableViewDataSource, NSTableViewDelegate, NSControlTextEditingDelegate>
+
+- (IBAction)filterTable:(id)sender;
+- (IBAction)toggleLookAllFieldsMode:(id)sender;
+- (IBAction)tableFilterClear:(id)sender;
+
+- (IBAction)toggleNegateClause:(id)sender;
+- (IBAction)toggleDistinctSelect:(id)sender;
+- (IBAction)setDefaultOperator:(id)sender;
+
+- (IBAction)closeSheet:(id)sender;
+- (IBAction)showDefaultOperaterHelp:(id)sender;
+
+- (void)updateFilterTableClause:(id)currentValue;
+
++ (NSString*)escapeFilterTableDefaultOperator:(NSString*)op;
+
+@end
+
+@implementation SPFilterTableController
+
+#pragma mark Public methods
+
+@synthesize target;
+@synthesize action;
+
+- (instancetype)init {
+ if ((self = [super initWithWindowNibName:@"FilterTableWindow"])) {
+ target = nil;
+ action = NULL;
+
+ prefs = [NSUserDefaults standardUserDefaults];
+ [prefs addObserver:self
+ forKeyPath:SPDisplayTableViewVerticalGridlines
+ options:NSKeyValueObservingOptionNew
+ context:FilterTableKVOContext];
+
+ filterTableData = [[NSMutableDictionary alloc] initWithCapacity:1];
+
+ filterTableNegate = NO;
+ filterTableDistinct = NO;
+ filterTableIsSwapped = NO;
+
+ lastEditedFilterTableValue = nil;
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ //TODO this should be changed to the variant with …context: after 10.6 support is removed!
+ [prefs removeObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines];
+
+ SPClear(filterTableData);
+ SPClear(lastEditedFilterTableValue);
+ SPClear(filterTableDefaultOperator);
+ [super dealloc];
+}
+
+- (void)showFilterTableWindow
+{
+ [[self window] makeKeyAndOrderFront:nil];
+ [filterTableWhereClause setContinuousSpellCheckingEnabled:NO];
+ [filterTableWhereClause setAutoindent:NO];
+ [filterTableWhereClause setAutoindentIgnoresEnter:NO];
+ [filterTableWhereClause setAutopair:[prefs boolForKey:SPCustomQueryAutoPairCharacters]];
+ [filterTableWhereClause setAutohelp:NO];
+ [filterTableWhereClause setAutouppercaseKeywords:[prefs boolForKey:SPCustomQueryAutoUppercaseKeywords]];
+ [filterTableWhereClause setCompletionWasReinvokedAutomatically:NO];
+ [filterTableWhereClause insertText:@""];
+ [filterTableWhereClause didChangeText];
+
+ [[filterTableView window] makeFirstResponder:filterTableView];
+}
+
+- (void)setFilterTableData:(NSData*)arcData
+{
+ if(!arcData) return;
+ NSDictionary *filterData = [NSUnarchiver unarchiveObjectWithData:arcData];
+ [filterTableData removeAllObjects];
+ [filterTableData addEntriesFromDictionary:filterData];
+ [[self window] makeKeyAndOrderFront:nil];
+ [filterTableView reloadData];
+}
+
+- (NSData*) filterTableData
+{
+ if(![[self window] isVisible]) return nil;
+
+ [filterTableView deselectAll:nil];
+
+ return [NSArchiver archivedDataWithRootObject:filterTableData];
+}
+
+- (NSString *)tableFilterString
+{
+ if([[[filterTableWhereClause textStorage] string] length]) {
+ if ([filterTableNegateCheckbox state] == NSOnState) {
+ return [NSString stringWithFormat:@"NOT (%@)", [[filterTableWhereClause textStorage] string]];
+ }
+ else {
+ return [[filterTableWhereClause textStorage] string];
+ }
+ }
+ else {
+ return nil;
+ }
+}
+
+- (void)setColumns:(NSArray *)dataColumns
+{
+ [self window]; // make sure window is loaded
+ // Clear filter table
+ [filterTableView abortEditing];
+ while ([[filterTableView tableColumns] count]) {
+ [NSArrayObjectAtIndex([filterTableView tableColumns], 0) setHeaderToolTip:nil]; // prevent crash #2414
+ [filterTableView removeTableColumn:NSArrayObjectAtIndex([filterTableView tableColumns], 0)];
+ }
+ // Clear filter table data
+ [filterTableData removeAllObjects];
+ [filterTableWhereClause setString:@""];
+
+ // Clear error state
+ [self setFilterError:0 message:nil sqlstate:nil];
+
+ if(dataColumns) {
+ // Add the new columns to the filterTable
+ for (NSDictionary *columnDefinition in dataColumns ) {
+ // Set up column for filterTable
+ NSTableColumn *filterCol = [[NSTableColumn alloc] initWithIdentifier:[columnDefinition objectForKey:@"datacolumnindex"]];
+ [[filterCol headerCell] setStringValue:[columnDefinition objectForKey:@"name"]];
+ [filterCol setEditable:YES];
+ SPTextAndLinkCell *filterDataCell = [[[SPTextAndLinkCell alloc] initTextCell:@""] autorelease];
+ [filterDataCell setEditable:YES];
+ [filterDataCell setLineBreakMode:NSLineBreakByTruncatingTail]; // add ellipsis for long values (default is to simply hide words)
+ [filterCol setDataCell:filterDataCell];
+ [filterTableView addTableColumn:filterCol];
+ [filterCol release];
+
+ [filterTableData setObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
+ [columnDefinition objectForKey:@"name"], @"name",
+ [columnDefinition objectForKey:@"typegrouping"], @"typegrouping",
+ [NSMutableArray arrayWithObjects:@"", @"", @"", @"", @"", @"", @"", @"", @"", @"", nil], SPTableContentFilterKey,
+ nil] forKey:[columnDefinition objectForKey:@"datacolumnindex"]];
+ }
+ }
+
+ [filterTableView reloadData];
+}
+
+- (BOOL)isDistinct
+{
+ return filterTableDistinct;
+}
+
+- (void)setFilterError:(NSUInteger)errorID message:(NSString *)message sqlstate:(NSString *)sqlstate
+{
+ if(errorID) {
+ [[self window] setTitle:[NSString stringWithFormat:@"%@ – %@", NSLocalizedString(@"Filter", @"filter label"), NSLocalizedString(@"WHERE clause not valid", @"WHERE clause not valid")]];
+ }
+ else {
+ [[self window] setTitle:NSLocalizedString(@"Filter", @"filter label")];
+ }
+}
+
+#pragma mark - Internal methods
+
+- (void)windowDidLoad
+{
+ [filterTableView setGridStyleMask:([prefs boolForKey:SPDisplayTableViewVerticalGridlines]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
+
+ // Modify the filter table split view sizes
+ [filterTableSplitView setMinSize:135 ofSubviewAtIndex:1];
+
+ // Init Filter Table GUI
+ [filterTableDistinctCheckbox setState:(filterTableDistinct) ? NSOnState : NSOffState];
+ [filterTableNegateCheckbox setState:(filterTableNegate) ? NSOnState : NSOffState];
+ [filterTableLiveSearchCheckbox setState:NSOffState];
+
+ filterTableDefaultOperator = [[[self class] escapeFilterTableDefaultOperator:[prefs objectForKey:SPFilterTableDefaultOperator]] retain];
+}
+
+- (IBAction)filterTable:(id)sender
+{
+ if(target && action) [target performSelector:action withObject:self];
+}
+
+/**
+ * Generate WHERE clause to look for last typed pattern in all fields
+ */
+- (IBAction)toggleLookAllFieldsMode:(id)sender
+{
+ [self updateFilterTableClause:sender];
+
+ // If live search is set perform filtering
+ if ([filterTableLiveSearchCheckbox state] == NSOnState) {
+ [self filterTable:filterTableFilterButton];
+ }
+}
+
+/**
+ * Clear the filter table
+ */
+- (IBAction)tableFilterClear:(id)sender
+{
+ [filterTableView abortEditing];
+
+ if(filterTableData && [filterTableData count]) {
+
+ // Clear filter data
+ for(NSNumber *col in [filterTableData allKeys])
+ {
+ [[filterTableData objectForKey:col] setObject:[NSMutableArray arrayWithObjects:@"", @"", @"", @"", @"", @"", @"", @"", @"", @"", nil] forKey:SPTableContentFilterKey];
+ }
+
+ [filterTableView reloadData];
+ [filterTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
+ [filterTableWhereClause setString:@""];
+
+ // Reload table
+ [self filterTable:nil];
+ }
+}
+
+/**
+ * Set filter table's Negate
+ */
+- (IBAction)toggleNegateClause:(id)sender
+{
+ filterTableNegate = !filterTableNegate;
+
+ if (filterTableNegate) {
+ [filterTableQueryTitle setStringValue:NSLocalizedString(@"WHERE NOT query", @"Title of filter preview area when the query WHERE is negated")];
+ }
+ else {
+ [filterTableQueryTitle setStringValue:NSLocalizedString(@"WHERE query", @"Title of filter preview area when the query WHERE is normal")];
+ }
+
+ // If live search is set perform filtering
+ if ([filterTableLiveSearchCheckbox state] == NSOnState) {
+ [self filterTable:filterTableFilterButton];
+ }
+}
+
+/**
+ * Set filter table's Distinct
+ */
+- (IBAction)toggleDistinctSelect:(id)sender
+{
+ filterTableDistinct = !filterTableDistinct;
+
+ [filterTableDistinctCheckbox setState:(filterTableDistinct) ? NSOnState : NSOffState];
+
+ // If live search is set perform filtering
+ if ([filterTableLiveSearchCheckbox state] == NSOnState) {
+ [self filterTable:filterTableFilterButton];
+ }
+}
+
+/**
+ * Set filter table's default operator
+ */
+- (IBAction)setDefaultOperator:(id)sender
+{
+ [[self window] makeFirstResponder:filterTableView];
+
+ // Load history
+ if([prefs objectForKey:SPFilterTableDefaultOperatorLastItems]) {
+ NSMutableArray *lastItems = [NSMutableArray array];
+
+ [lastItems addObject:@"LIKE '%@%'"];
+
+ for(NSString* item in [prefs objectForKey:SPFilterTableDefaultOperatorLastItems])
+ {
+ [lastItems addObject:item];
+ }
+
+ [filterTableSetDefaultOperatorValue removeAllItems];
+ [filterTableSetDefaultOperatorValue addItemsWithObjectValues:lastItems];
+ }
+
+ [filterTableSetDefaultOperatorValue setStringValue:[prefs objectForKey:SPFilterTableDefaultOperator]];
+
+ [NSApp beginSheet:filterTableSetDefaultOperatorSheet
+ modalForWindow:[self window]
+ modalDelegate:self
+ didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
+ contextInfo:SPTableFilterSetDefaultOperator];
+}
+
+/**
+ * Close an open sheet.
+ */
+- (void)sheetDidEnd:(id)sheet returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo
+{
+ [sheet orderOut:self];
+
+ if([contextInfo isEqualToString:SPTableFilterSetDefaultOperator]) {
+ if(returnCode) {
+ if(filterTableDefaultOperator) [filterTableDefaultOperator release];
+ NSString *newOperator = [filterTableSetDefaultOperatorValue stringValue];
+ filterTableDefaultOperator = [[[self class] escapeFilterTableDefaultOperator:newOperator] retain];
+ [prefs setObject:newOperator forKey:SPFilterTableDefaultOperator];
+
+ if(![newOperator isMatchedByRegex:@"(?i)like\\s+['\"]%@%['\"]\\s*"]) {
+ if(![prefs objectForKey:SPFilterTableDefaultOperatorLastItems])
+ [prefs setObject:[NSMutableArray array] forKey:SPFilterTableDefaultOperatorLastItems];
+
+ NSMutableArray *lastItems = [NSMutableArray array];
+ [lastItems setArray:[prefs objectForKey:SPFilterTableDefaultOperatorLastItems]];
+
+ if([lastItems containsObject:newOperator])
+ [lastItems removeObject:newOperator];
+ if([lastItems count] > 0)
+ [lastItems insertObject:newOperator atIndex:0];
+ else
+ [lastItems addObject:newOperator];
+ // Remember only the last 15 items
+ if([lastItems count] > 15)
+ while([lastItems count] > 15)
+ [filterTableSetDefaultOperatorValue removeItemAtIndex:[lastItems count]-1];
+
+ [prefs setObject:lastItems forKey:SPFilterTableDefaultOperatorLastItems];
+ }
+ [self updateFilterTableClause:nil];
+ }
+ }
+}
+
+/**
+ * Closes the current sheet and stops the modal session
+ */
+- (IBAction)closeSheet:(id)sender
+{
+ [NSApp endSheet:[sender window] returnCode:[sender tag]];
+ [[sender window] orderOut:self];
+}
+
+/**
+ * Opens the content filter help page in the default browser.
+ */
+- (IBAction)showDefaultOperaterHelp:(id)sender
+{
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:SPLOCALIZEDURL_CONTENTFILTERHELP]];
+}
+
+/**
+ * Update WHERE clause in filter table window.
+ *
+ * @param currentValue If currentValue == nil take the data from filterTableData, if currentValue == filterTableSearchAllFields
+ * generate a WHERE clause to search in all given fields, if currentValue == a string take this string as table cell data of the
+ * currently edited table cell
+ */
+- (void)updateFilterTableClause:(id)currentValue
+{
+ NSMutableString *clause = [NSMutableString string];
+ NSInteger numberOfRows = [self numberOfRowsInTableView:filterTableView];
+ NSInteger numberOfCols = [[filterTableView tableColumns] count];
+ NSRange opRange, defopRange;
+
+ BOOL lookInAllFields = NO;
+
+ NSString *re1 = @"^\\s*(<[=>]?|>=?|!?=|≠|≤|≥)\\s*(.*?)\\s*$";
+ NSString *re2 = @"^\\s*(.*)\\s+(.*?)\\s*$";
+
+ NSInteger editedRow = [filterTableView editedRow];
+
+ if (currentValue == filterTableSearchAllFields) {
+ numberOfRows = 1;
+ lookInAllFields = YES;
+ }
+
+ [filterTableWhereClause setString:@""];
+
+ for (NSInteger i = 0; i < numberOfRows; i++)
+ {
+ NSInteger numberOfValues = 0;
+
+ for (NSInteger anIndex = 0; anIndex < numberOfCols; anIndex++)
+ {
+ NSString *filterCell = nil;
+ NSDictionary *filterCellData = [NSDictionary dictionaryWithDictionary:[filterTableData objectForKey:[NSString stringWithFormat:@"%ld", (long)anIndex]]];
+
+ // Take filterTableData
+ if (!currentValue) {
+ filterCell = NSArrayObjectAtIndex([filterCellData objectForKey:SPTableContentFilterKey], i);
+ }
+ // Take last edited value to create the OR clause
+ else if (lookInAllFields) {
+ if (lastEditedFilterTableValue && [lastEditedFilterTableValue length]) {
+ filterCell = lastEditedFilterTableValue;
+ }
+ else {
+ [filterTableWhereClause setString:@""];
+ [filterTableWhereClause insertText:@""];
+ [filterTableWhereClause scrollRangeToVisible:NSMakeRange(0, 0)];
+
+ // If live search is set perform filtering
+ if ([filterTableLiveSearchCheckbox state] == NSOnState) {
+ [self filterTable:filterTableFilterButton];
+ }
+ }
+ }
+ // Take value from currently edited table cell
+ else if ([currentValue isKindOfClass:[NSString class]]) {
+ if (i == editedRow && anIndex == [[NSArrayObjectAtIndex([filterTableView tableColumns], [filterTableView editedColumn]) identifier] integerValue]) {
+ filterCell = (NSString*)currentValue;
+ }
+ else {
+ filterCell = NSArrayObjectAtIndex([filterCellData objectForKey:SPTableContentFilterKey], i);
+ }
+ }
+
+ if ([filterCell length]) {
+
+ // Recode special operators
+ filterCell = [filterCell stringByReplacingOccurrencesOfRegex:@"^\\s*≠" withString:@"!="];
+ filterCell = [filterCell stringByReplacingOccurrencesOfRegex:@"^\\s*≤" withString:@"<="];
+ filterCell = [filterCell stringByReplacingOccurrencesOfRegex:@"^\\s*≥" withString:@">="];
+
+ if (numberOfValues) {
+ [clause appendString:(lookInAllFields) ? @" OR " : @" AND "];
+ }
+
+ NSString *fieldName = [[filterCellData objectForKey:@"name"] backtickQuotedString];
+ NSString *filterTableDefaultOperatorWithFieldName = [filterTableDefaultOperator stringByReplacingOccurrencesOfString:@"`@`" withString:fieldName];
+
+ opRange = [filterCell rangeOfString:@"`@`"];
+ defopRange = [filterTableDefaultOperator rangeOfString:@"`@`"];
+
+ // if cell data begins with ' or " treat it as it is
+ // by checking if default operator by itself contains a ' or " - if so
+ // remove first and if given the last ' or "
+ if ([filterCell isMatchedByRegex:@"^\\s*['\"]"]) {
+ if ([filterTableDefaultOperator isMatchedByRegex:@"['\"]"]) {
+ NSArray *matches = [filterCell arrayOfCaptureComponentsMatchedByRegex:@"^\\s*(['\"])(.*)\\1\\s*$"];
+
+ if ([matches count] && [matches = NSArrayObjectAtIndex(matches, 0) count] == 3) {
+ [clause appendFormat:[NSString stringWithFormat:@"%%@ %@", filterTableDefaultOperatorWithFieldName], fieldName, NSArrayObjectAtIndex(matches, 2)];
+ }
+ else {
+ matches = [filterCell arrayOfCaptureComponentsMatchedByRegex:@"^\\s*(['\"])(.*)\\s*$"];
+
+ if ([matches count] && [matches = NSArrayObjectAtIndex(matches, 0) count] == 3) {
+ [clause appendFormat:[NSString stringWithFormat:@"%%@ %@", filterTableDefaultOperatorWithFieldName], fieldName, NSArrayObjectAtIndex(matches, 2)];
+ }
+ }
+ }
+ else {
+ [clause appendFormat:[NSString stringWithFormat:@"%%@ %@", filterTableDefaultOperatorWithFieldName], fieldName, filterCell];
+ }
+ }
+ // If cell contains the field name placeholder
+ else if (opRange.length || defopRange.length) {
+ filterCell = [filterCell stringByReplacingOccurrencesOfString:@"`@`" withString:fieldName];
+
+ if (defopRange.length) {
+ [clause appendFormat:filterTableDefaultOperatorWithFieldName, [filterCell stringByReplacingOccurrencesOfString:@"`@`" withString:fieldName]];
+ }
+ else {
+ [clause appendString:[filterCell stringByReplacingOccurrencesOfString:@"`@`" withString:fieldName]];
+ }
+ }
+ // If cell is equal to NULL
+ else if ([filterCell isMatchedByRegex:@"(?i)^\\s*null\\s*$"]) {
+ [clause appendFormat:@"%@ IS NULL", fieldName];
+ }
+ // If cell starts with an operator
+ else if ([filterCell isMatchedByRegex:re1]) {
+ NSArray *matches = [filterCell arrayOfCaptureComponentsMatchedByRegex:re1];
+
+ if ([matches count] && [matches = NSArrayObjectAtIndex(matches, 0) count] == 3) {
+ [clause appendFormat:@"%@ %@ %@", fieldName, NSArrayObjectAtIndex(matches, 1), NSArrayObjectAtIndex(matches, 2)];
+ }
+ }
+ // If cell consists of at least two words treat the first as operator and the rest as argument
+ else if ([filterCell isMatchedByRegex:re2]) {
+ NSArray *matches = [filterCell arrayOfCaptureComponentsMatchedByRegex:re2];
+
+ if ([matches count] && [matches = NSArrayObjectAtIndex(matches,0) count] == 3) {
+ [clause appendFormat:@"%@ %@ %@", fieldName, [NSArrayObjectAtIndex(matches, 1) uppercaseString], NSArrayObjectAtIndex(matches, 2)];
+ }
+ }
+ // Apply the default operator
+ else {
+ [clause appendFormat:[NSString stringWithFormat:@"%%@ %@", filterTableDefaultOperatorWithFieldName], fieldName, filterCell];
+ }
+
+ numberOfValues++;
+ }
+ }
+
+ if (numberOfValues) {
+ [clause appendString:@"\nOR\n"];
+ }
+ }
+
+ // Remove last " OR " if any
+ [filterTableWhereClause setString:[clause length] > 3 ? [clause substringToIndex:([clause length] - 4)] : @""];
+
+ // Update syntax highlighting and uppercasing
+ [filterTableWhereClause insertText:@""];
+ [filterTableWhereClause scrollRangeToVisible:NSMakeRange(0, 0)];
+
+ // If live search is set perform filtering
+ if ([filterTableLiveSearchCheckbox state] == NSOnState) {
+ [self filterTable:filterTableFilterButton];
+ }
+}
+
+#pragma mark - TableView datasource methods
+
+- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
+{
+ if (filterTableIsSwapped) {
+ [[[filterTableData objectForKey:@(rowIndex)] objectForKey:SPTableContentFilterKey] replaceObjectAtIndex:([[tableColumn identifier] integerValue] - 1) withObject:(NSString *)object];
+ }
+ else {
+ [[[filterTableData objectForKey:[tableColumn identifier]] objectForKey:SPTableContentFilterKey] replaceObjectAtIndex:rowIndex withObject:(NSString *)object];
+ }
+
+ [self updateFilterTableClause:nil];
+}
+
+- (NSInteger)numberOfRowsInTableView:(SPCopyTable *)tableView
+{
+ return filterTableIsSwapped ? [filterTableData count] : [[[filterTableData objectForKey:@"0"] objectForKey:SPTableContentFilterKey] count];
+}
+
+- (id)tableView:(SPCopyTable *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
+{
+ NSUInteger columnIndex = [[tableColumn identifier] integerValue];
+
+ if (filterTableIsSwapped) {
+ // First column shows the field names
+ if (columnIndex == 0) {
+ return [[[NSTableHeaderCell alloc] initTextCell:[[filterTableData objectForKey:[NSNumber numberWithInteger:rowIndex]] objectForKey:@"name"]] autorelease];
+ }
+
+ return NSArrayObjectAtIndex([[filterTableData objectForKey:[NSNumber numberWithInteger:rowIndex]] objectForKey:SPTableContentFilterKey], columnIndex - 1);
+ }
+
+ return NSArrayObjectAtIndex([[filterTableData objectForKey:[tableColumn identifier]] objectForKey:SPTableContentFilterKey], rowIndex);
+}
+
+#pragma mark - TableView delegate methods
+
+- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)rowIndex
+{
+ return YES;
+}
+
+- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
+{
+ //if ([tableDocumentInstance isWorking]) return NO;
+
+ return (filterTableIsSwapped && [[tableColumn identifier] integerValue] == 0) ? NO : YES;
+}
+
+- (void)tableView:(SPCopyTable *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
+{
+ if (filterTableIsSwapped && [[tableColumn identifier] integerValue] == 0) {
+ [cell setDrawsBackground:YES];
+ [cell setBackgroundColor:[NSColor lightGrayColor]];
+ } else {
+ [cell setDrawsBackground:NO];
+ }
+}
+
+- (NSString *)tableView:(NSTableView *)tableView toolTipForCell:(id)aCell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row mouseLocation:(NSPoint)mouseLocation
+{
+ return nil;
+}
+
+#pragma mark - Control delegate methods
+
+- (void)controlTextDidChange:(NSNotification *)notification
+{
+ if ([notification object] == filterTableView) {
+
+ NSString *string = [[[[notification userInfo] objectForKey:@"NSFieldEditor"] textStorage] string];
+
+ if (string && [string length]) {
+ if (lastEditedFilterTableValue) [lastEditedFilterTableValue release];
+
+ lastEditedFilterTableValue = [[NSString stringWithString:string] retain];
+ }
+
+ [self updateFilterTableClause:string];
+ }
+}
+
+- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)editor
+{
+ return YES;
+}
+
+- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)aFieldEditor
+{
+ return YES;
+}
+
+- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command
+{
+ // Check firstly if SPCopyTable can handle command
+ if ([control control:control textView:textView doCommandBySelector:command]) return YES;
+
+ // Trap the escape key
+ if ([[control window] methodForSelector:command] == [[control window] methodForSelector:@selector(cancelOperation:)]) {
+ // Abort editing
+ [control abortEditing];
+
+ return YES;
+ }
+
+ return NO;
+}
+
+#pragma mark - KVO
+
+/**
+ * This method is called as part of Key Value Observing which is used to watch for prefernce changes which effect the interface.
+ */
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+ // a parent class (or cocoa) can also use KVO, so we need to watch out to only catch those KVO messages we requested
+ if(context == FilterTableKVOContext) {
+ // Display table veiew vertical gridlines preference changed
+ if ([keyPath isEqualToString:SPDisplayTableViewVerticalGridlines]) {
+ [filterTableView setGridStyleMask:([[change objectForKey:NSKeyValueChangeNewKey] boolValue]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
+ }
+ }
+ else {
+ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+ }
+}
+
+#pragma mark -
+
+/**
+ * Escape passed operator for usage as filterTableDefaultOperator.
+ */
++ (NSString*)escapeFilterTableDefaultOperator:(NSString *)op
+{
+ if (!op) return @"";
+
+ NSMutableString *newOp = [[[NSMutableString alloc] initWithCapacity:[op length]] autorelease];
+
+ [newOp setString:op];
+ [newOp replaceOccurrencesOfRegex:@"%" withString:@"%%"];
+ [newOp replaceOccurrencesOfRegex:@"(?<!`)@(?!=`)" withString:@"%@"];
+
+ return newOp;
+}
+
+@end
+
diff --git a/Source/SPHistoryController.m b/Source/SPHistoryController.m
index c39421a9..8a0554fe 100644
--- a/Source/SPHistoryController.m
+++ b/Source/SPHistoryController.m
@@ -250,7 +250,7 @@
NSDictionary *contentSelectedRows = [[tableContentInstance onMainThread] selectionDetailsAllowingIndexSelection:YES];
NSRect contentViewport = [[tableContentInstance onMainThread] viewport];
NSDictionary *contentFilter = [[tableContentInstance onMainThread] filterSettings];
- NSData *filterTableData = [tableContentInstance filterTableData];
+ NSData *filterTableData = [[tableContentInstance onMainThread] filterTableData];
if (!theDatabase) return;
// If a table is selected, save state information
diff --git a/Source/SPTableContent.h b/Source/SPTableContent.h
index d47dd467..c8f7100a 100644
--- a/Source/SPTableContent.h
+++ b/Source/SPTableContent.h
@@ -43,10 +43,8 @@
@class SPDatabaseDocument;
@class SPTablesList;
@class SPTableStructure;
-#ifndef SP_CODA
-@class SPSplitView;
-#endif
@class SPTableContentFilterController;
+@class SPFilterTableController;
typedef NS_ENUM(NSInteger, SPTableContentFilterSource) {
SPTableContentFilterSourceNone = -1,
@@ -102,21 +100,8 @@ typedef NS_ENUM(NSInteger, SPTableContentFilterSource) {
#ifndef SP_CODA
IBOutlet NSStepper *paginationPageStepper;
- IBOutlet SPCopyTable *filterTableView;
- IBOutlet NSPanel *filterTableWindow;
- IBOutlet SPSplitView *filterTableSplitView;
- IBOutlet NSTextField *filterTableQueryTitle;
- IBOutlet NSButton *filterTableFilterButton;
- IBOutlet NSButton *filterTableClearButton;
- IBOutlet SPTextView *filterTableWhereClause;
- IBOutlet NSButton *filterTableNegateCheckbox;
- IBOutlet NSButton *filterTableDistinctCheckbox;
- IBOutlet NSButton *filterTableLiveSearchCheckbox;
- IBOutlet NSButton *filterTableSearchAllFields;
- IBOutlet NSPanel *filterTableSetDefaultOperatorSheet;
- IBOutlet NSComboBox* filterTableSetDefaultOperatorValue;
-
IBOutlet SPTableContentFilterController *filterControllerInstance;
+ IBOutlet SPFilterTableController *filterTableController;
#endif
SPMySQLConnection *mySQLConnection;
@@ -140,12 +125,6 @@ typedef NS_ENUM(NSInteger, SPTableContentFilterSource) {
NSUInteger contentPage;
#ifndef SP_CODA
- NSMutableDictionary *filterTableData;
- BOOL filterTableNegate;
- BOOL filterTableDistinct;
- BOOL filterTableIsSwapped;
- NSString *filterTableDefaultOperator;
- NSString *lastEditedFilterTableValue;
SPTableContentFilterSource activeFilter;
NSString *schemeFilter;
#endif
@@ -243,14 +222,7 @@ typedef NS_ENUM(NSInteger, SPTableContentFilterSource) {
- (void)removeRowSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo;
// Filter Table
-- (IBAction)tableFilterClear:(id)sender;
- (IBAction)showFilterTable:(id)sender;
-- (IBAction)toggleNegateClause:(id)sender;
-- (IBAction)toggleDistinctSelect:(id)sender;
-- (IBAction)setDefaultOperator:(id)sender;
-- (IBAction)toggleLookAllFieldsMode:(id)sender;
-- (IBAction)closeSheet:(id)sender;
-- (IBAction)showDefaultOperaterHelp:(id)sender;
// Data accessors
- (NSArray *)currentResult;
@@ -309,7 +281,5 @@ typedef NS_ENUM(NSInteger, SPTableContentFilterSource) {
#pragma mark - SPTableContentFilter
- (void)makeContentFilterHaveFocus;
-- (void)updateFilterTableClause:(id)currentValue;
-- (NSString*)escapeFilterTableDefaultOperator:(NSString*)op;
@end
diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m
index 934745f6..8d1a19a3 100644
--- a/Source/SPTableContent.m
+++ b/Source/SPTableContent.m
@@ -40,9 +40,6 @@
#import "SPTableData.h"
#import "SPQueryController.h"
#import "SPTextAndLinkCell.h"
-#ifndef SP_CODA
-#import "SPSplitView.h"
-#endif
#import "SPFieldEditorController.h"
#import "SPTooltip.h"
#import "RegexKitLite.h"
@@ -60,6 +57,7 @@
#import "SPTableFilterParser.h"
#import "SPFunctions.h"
#import "SPTableContentFilterController.h"
+#import "SPFilterTableController.h"
#import <pthread.h>
#import <SPMySQL/SPMySQL.h>
@@ -71,10 +69,6 @@
*/
static void *TableContentKVOContext = &TableContentKVOContext;
-#ifndef SP_CODA
-static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOperator";
-#endif
-
@interface SPTableContent ()
- (BOOL)cancelRowEditing;
@@ -127,18 +121,11 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
tableValues = [[SPDataStorage alloc] init];
dataColumns = [[NSMutableArray alloc] init];
oldRow = [[NSMutableArray alloc] init];
-#ifndef SP_CODA
- filterTableData = [[NSMutableDictionary alloc] initWithCapacity:1];
-#endif
tableRowsCount = 0;
previousTableRowsCount = 0;
#ifndef SP_CODA
- filterTableNegate = NO;
- filterTableDistinct = NO;
- filterTableIsSwapped = NO;
- lastEditedFilterTableValue = nil;
activeFilter = SPTableContentFilterSourceNone;
schemeFilter = nil;
paginationPopover = nil;
@@ -198,7 +185,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
// Set the table content view's vertical gridlines if required
[tableContentView setGridStyleMask:([prefs boolForKey:SPDisplayTableViewVerticalGridlines]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
- [filterTableView setGridStyleMask:([prefs boolForKey:SPDisplayTableViewVerticalGridlines]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
// Set the double-click action in blank areas of the table to create new rows
[tableContentView setEmptyDoubleClickAction:@selector(addRow:)];
@@ -238,25 +224,10 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
[paginationView setFrame:paginationViewFrame];
[contentViewPane addSubview:paginationView];
}
-
- // Modify the filter table split view sizes
- [filterTableSplitView setMinSize:135 ofSubviewAtIndex:1];
#endif
[tableContentView setFieldEditorSelectedRange:NSMakeRange(0,0)];
-#ifndef SP_CODA
- // Init Filter Table GUI
- [filterTableDistinctCheckbox setState:(filterTableDistinct) ? NSOnState : NSOffState];
- [filterTableNegateCheckbox setState:(filterTableNegate) ? NSOnState : NSOffState];
- [filterTableLiveSearchCheckbox setState:NSOffState];
-#endif
-#ifndef SP_CODA /* patch */
- filterTableDefaultOperator = [[self escapeFilterTableDefaultOperator:[prefs objectForKey:SPFilterTableDefaultOperator]] retain];
-#else
-// filterTableDefaultOperator = [[self escapeFilterTableDefaultOperator:nil] retain];
-#endif
-
[prefs addObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines options:NSKeyValueObservingOptionNew context:TableContentKVOContext];
[prefs addObserver:self forKeyPath:SPGlobalResultTableFont options:NSKeyValueObservingOptionNew context:TableContentKVOContext];
[prefs addObserver:self forKeyPath:SPDisplayBinaryDataAsHex options:NSKeyValueObservingOptionNew context:TableContentKVOContext];
@@ -273,6 +244,9 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
object:contentAreaContainer];
[filterControllerInstance setTarget:self];
[filterControllerInstance setAction:@selector(filterTable:)];
+
+ [filterTableController setTarget:self];
+ [filterTableController setAction:@selector(filterTable:)];
// Add observers for document task activity
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -406,14 +380,7 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
[self clearDetailsToRestore];
#ifndef SP_CODA
- // Clear filter table
- while ([[filterTableView tableColumns] count]) {
- [NSArrayObjectAtIndex([filterTableView tableColumns], 0) setHeaderToolTip:nil]; // prevent crash #2414
- [filterTableView removeTableColumn:NSArrayObjectAtIndex([filterTableView tableColumns], 0)];
- }
- // Clear filter table data
- [filterTableData removeAllObjects];
- [filterTableWhereClause setString:@""];
+ [filterTableController setColumns:nil];
activeFilter = SPTableContentFilterSourceNone;
#endif
}
@@ -432,10 +399,8 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
#endif
NSArray *columnNames;
NSMutableDictionary *preservedColumnWidths = nil;
- NSTableColumn *theCol;
-#ifndef SP_CODA
- NSTableColumn *filterCol;
-#endif
+ NSTableColumn *theCol;
+
BOOL enableInteraction =
#ifndef SP_CODA /* checking toolbar state */
![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableContent] ||
@@ -511,14 +476,7 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
}
#ifndef SP_CODA
// Remove existing columns from the filter table
- [filterTableView abortEditing];
- while ([[filterTableView tableColumns] count]) {
- [NSArrayObjectAtIndex([filterTableView tableColumns], 0) setHeaderToolTip:nil]; // prevent crash #2414
- [filterTableView removeTableColumn:NSArrayObjectAtIndex([filterTableView tableColumns], 0)];
- }
- // Clear filter table data
- [filterTableData removeAllObjects];
- [filterTableWhereClause setString:@""];
+ [filterTableController setColumns:nil];
// TODO code smell
//...but keep it, if the rule filter is the active one
if(activeFilter != SPTableContentFilterSourceRuleFilter) activeFilter = SPTableContentFilterSourceNone;
@@ -557,7 +515,7 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
#endif
[tableContentView setRowHeight:2.0f+NSSizeToCGSize([@"{ǞṶḹÜ∑zgyf" sizeWithAttributes:@{NSFontAttributeName : tableFont}]).height];
- // Add the new columns to the table and filterTable
+ // Add the new columns to the table
for (NSDictionary *columnDefinition in dataColumns ) {
// Set up the column
@@ -578,24 +536,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
[theCol setEditable:YES];
-#ifndef SP_CODA
- // Set up column for filterTable
- filterCol = [[NSTableColumn alloc] initWithIdentifier:[columnDefinition objectForKey:@"datacolumnindex"]];
- [[filterCol headerCell] setStringValue:[columnDefinition objectForKey:@"name"]];
- [filterCol setEditable:YES];
- SPTextAndLinkCell *filterDataCell = [[[SPTextAndLinkCell alloc] initTextCell:@""] autorelease];
- [filterDataCell setEditable:YES];
- [filterCol setDataCell:filterDataCell];
- [filterTableView addTableColumn:filterCol];
- [filterCol release];
-
- [filterTableData setObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
- [columnDefinition objectForKey:@"name"], @"name",
- [columnDefinition objectForKey:@"typegrouping"], @"typegrouping",
- [NSMutableArray arrayWithObjects:@"", @"", @"", @"", @"", @"", @"", @"", @"", @"", nil], SPTableContentFilterKey,
- nil] forKey:[columnDefinition objectForKey:@"datacolumnindex"]];
-#endif
-
// Set up the data cell depending on the column type
id dataCell;
if ([[columnDefinition objectForKey:@"typegrouping"] isEqualToString:@"enum"]) {
@@ -665,12 +605,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
[theCol release];
}
-#ifndef SP_CODA
- [filterTableView setDelegate:self];
- [filterTableView setDataSource:self];
- [filterTableView reloadData];
-#endif
-
// If the table has been reloaded and the previously selected sort column is still present, reselect it.
if (sortColumnNumberToRestore != NSNotFound) {
theCol = [tableContentView tableColumnWithIdentifier:[NSString stringWithFormat:@"%lld", (long long)sortColumnNumberToRestore]];
@@ -700,6 +634,7 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
currentFirstResponder = [currentFirstResponder delegate];
}
+ [filterTableController setColumns:dataColumns];
// Enable and initialize filter fields (with tags for position of menu item and field position)
[filterControllerInstance updateFiltersFrom:self];
// Restore preserved filter settings if appropriate and valid
@@ -732,10 +667,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
if (!previousTableRowsCount) {
[self clearTableValues];
}
-#ifndef SP_CODA
- [filterTableView reloadData];
-#endif
-
}
- (NSString *)selectedTable
@@ -785,17 +716,17 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
// Notify any listeners that a query has started
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance];
+ // Add a filter string if appropriate
+ filterString = [[self onMainThread] tableFilterString];
+
// Start construction of the query string
queryString = [NSMutableString stringWithFormat:@"SELECT %@%@ FROM %@",
#ifndef SP_CODA
- (activeFilter == SPTableContentFilterSourceTableFilter && [self tableFilterString] && filterTableDistinct) ? @"DISTINCT " :
+ (activeFilter == SPTableContentFilterSourceTableFilter && filterString && [filterTableController isDistinct]) ? @"DISTINCT " :
#endif
@"",
[self fieldListForQuery], [selectedTable backtickQuotedString]];
- // Add a filter string if appropriate
- filterString = [[self onMainThread] tableFilterString];
-
if ([filterString length]) {
[queryString appendFormat:@" WHERE %@", filterString];
isFiltered = YES;
@@ -983,7 +914,9 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
#ifndef SP_CODA
// Filter task came from filter table
else if(activeFilter == SPTableContentFilterSourceTableFilter) {
- [filterTableWindow setTitle:[NSString stringWithFormat:@"%@ – %@", NSLocalizedString(@"Filter", @"filter label"), NSLocalizedString(@"WHERE clause not valid", @"WHERE clause not valid")]];
+ [[filterTableController onMainThread] setFilterError:[mySQLConnection lastErrorID]
+ message:[mySQLConnection lastErrorMessage]
+ sqlstate:[mySQLConnection lastSqlstate]];
}
}
#endif
@@ -992,7 +925,7 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
#ifndef SP_CODA
// Trigger a full reload if required
if (fullTableReloadRequired) [self reloadTable:self];
- [[filterTableWindow onMainThread] setTitle:NSLocalizedString(@"Filter", @"filter label")];
+ [[filterTableController onMainThread] setFilterError:0 message:nil sqlstate:nil];
#endif
}
}
@@ -1069,18 +1002,8 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
}
// Call did come from filter table and is filter table window still open?
- if(activeFilter == SPTableContentFilterSourceTableFilter && [filterTableWindow isVisible]) {
- if([[[filterTableWhereClause textStorage] string] length]) {
- if ([filterTableNegateCheckbox state] == NSOnState) {
- return [NSString stringWithFormat:@"NOT (%@)", [[filterTableWhereClause textStorage] string]];
- }
- else {
- return [[filterTableWhereClause textStorage] string];
- }
- }
- else {
- return nil;
- }
+ if(activeFilter == SPTableContentFilterSourceTableFilter && [[filterTableController window] isVisible]) {
+ return [filterTableController tableFilterString];
}
#endif
if(activeFilter == SPTableContentFilterSourceRuleFilter && showFilterRuleEditor) {
@@ -1317,7 +1240,7 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
#ifndef SP_CODA
// If the filter table is being used - the advanced filter - switch type
- if(sender == filterTableFilterButton) {
+ if(sender == filterTableController) {
activeFilter = SPTableContentFilterSourceTableFilter;
}
@@ -3054,46 +2977,7 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
}
-/**
- * Close an open sheet.
- */
-- (void)sheetDidEnd:(id)sheet returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo
-{
-#ifndef SP_CODA
- [sheet orderOut:self];
-
- if([contextInfo isEqualToString:SPTableFilterSetDefaultOperator]) {
- if(returnCode) {
- if(filterTableDefaultOperator) [filterTableDefaultOperator release];
- NSString *newOperator = [filterTableSetDefaultOperatorValue stringValue];
- filterTableDefaultOperator = [[self escapeFilterTableDefaultOperator:newOperator] retain];
- [prefs setObject:newOperator forKey:SPFilterTableDefaultOperator];
-
- if(![newOperator isMatchedByRegex:@"(?i)like\\s+['\"]%@%['\"]\\s*"]) {
- if(![prefs objectForKey:SPFilterTableDefaultOperatorLastItems])
- [prefs setObject:[NSMutableArray array] forKey:SPFilterTableDefaultOperatorLastItems];
-
- NSMutableArray *lastItems = [NSMutableArray array];
- [lastItems setArray:[prefs objectForKey:SPFilterTableDefaultOperatorLastItems]];
-
- if([lastItems containsObject:newOperator])
- [lastItems removeObject:newOperator];
- if([lastItems count] > 0)
- [lastItems insertObject:newOperator atIndex:0];
- else
- [lastItems addObject:newOperator];
- // Remember only the last 15 items
- if([lastItems count] > 15)
- while([lastItems count] > 15)
- [filterTableSetDefaultOperatorValue removeItemAtIndex:[lastItems count]-1];
-
- [prefs setObject:lastItems forKey:SPFilterTableDefaultOperatorLastItems];
- }
- [self updateFilterTableClause:nil];
- }
- }
-#endif
-}
+
/**
* Show Error sheet (can be called from inside of a endSheet selector)
@@ -3290,160 +3174,11 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
#pragma mark Filter Table
/**
- * Clear the filter table
- */
-- (IBAction)tableFilterClear:(id)sender
-{
-#ifndef SP_CODA
-
- [filterTableView abortEditing];
-
- if(filterTableData && [filterTableData count]) {
-
- // Clear filter data
- for(NSNumber *col in [filterTableData allKeys])
- {
- [[filterTableData objectForKey:col] setObject:[NSMutableArray arrayWithObjects:@"", @"", @"", @"", @"", @"", @"", @"", @"", @"", nil] forKey:SPTableContentFilterKey];
- }
-
- [filterTableView reloadData];
- [filterTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
- [filterTableWhereClause setString:@""];
-
- // Reload table
- [self filterTable:nil];
- }
-#endif
-}
-
-/**
* Show filter table
*/
- (IBAction)showFilterTable:(id)sender
{
-#ifndef SP_CODA
- [filterTableWindow makeKeyAndOrderFront:nil];
- [filterTableWhereClause setContinuousSpellCheckingEnabled:NO];
- [filterTableWhereClause setAutoindent:NO];
- [filterTableWhereClause setAutoindentIgnoresEnter:NO];
- [filterTableWhereClause setAutopair:[prefs boolForKey:SPCustomQueryAutoPairCharacters]];
- [filterTableWhereClause setAutohelp:NO];
- [filterTableWhereClause setAutouppercaseKeywords:[prefs boolForKey:SPCustomQueryAutoUppercaseKeywords]];
- [filterTableWhereClause setCompletionWasReinvokedAutomatically:NO];
- [filterTableWhereClause insertText:@""];
- [filterTableWhereClause didChangeText];
-
- [[filterTableView window] makeFirstResponder:filterTableView];
-#endif
-}
-
-/**
- * Set filter table's Negate
- */
-- (IBAction)toggleNegateClause:(id)sender
-{
-#ifndef SP_CODA
- filterTableNegate = !filterTableNegate;
-
- if (filterTableNegate) {
- [filterTableQueryTitle setStringValue:NSLocalizedString(@"WHERE NOT query", @"Title of filter preview area when the query WHERE is negated")];
- }
- else {
- [filterTableQueryTitle setStringValue:NSLocalizedString(@"WHERE query", @"Title of filter preview area when the query WHERE is normal")];
- }
-
- // If live search is set perform filtering
- if ([filterTableLiveSearchCheckbox state] == NSOnState) {
- [self filterTable:filterTableFilterButton];
- }
-#endif
-
-}
-
-/**
- * Set filter table's Distinct
- */
-- (IBAction)toggleDistinctSelect:(id)sender
-{
-#ifndef SP_CODA
- filterTableDistinct = !filterTableDistinct;
-
- [filterTableDistinctCheckbox setState:(filterTableDistinct) ? NSOnState : NSOffState];
-
- // If live search is set perform filtering
- if ([filterTableLiveSearchCheckbox state] == NSOnState) {
- [self filterTable:filterTableFilterButton];
- }
-#endif
-
-}
-
-/**
- * Set filter table's default operator
- */
-- (IBAction)setDefaultOperator:(id)sender
-{
-#ifndef SP_CODA
-
- [filterTableWindow makeFirstResponder:filterTableView];
-
- // Load history
- if([prefs objectForKey:SPFilterTableDefaultOperatorLastItems]) {
- NSMutableArray *lastItems = [NSMutableArray array];
-
- [lastItems addObject:@"LIKE '%@%'"];
-
- for(NSString* item in [prefs objectForKey:SPFilterTableDefaultOperatorLastItems])
- {
- [lastItems addObject:item];
- }
-
- [filterTableSetDefaultOperatorValue removeAllItems];
- [filterTableSetDefaultOperatorValue addItemsWithObjectValues:lastItems];
- }
-
- [filterTableSetDefaultOperatorValue setStringValue:[prefs objectForKey:SPFilterTableDefaultOperator]];
-
- [NSApp beginSheet:filterTableSetDefaultOperatorSheet
- modalForWindow:filterTableWindow
- modalDelegate:self
- didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
- contextInfo:SPTableFilterSetDefaultOperator];
-#endif
-
-}
-
-/**
- * Generate WHERE clause to look for last typed pattern in all fields
- */
-- (IBAction)toggleLookAllFieldsMode:(id)sender
-{
- [self updateFilterTableClause:sender];
-
-#ifndef SP_CODA
- // If live search is set perform filtering
- if ([filterTableLiveSearchCheckbox state] == NSOnState) {
- [self filterTable:filterTableFilterButton];
- }
-#endif
-
-}
-
-/**
- * Closes the current sheet and stops the modal session
- */
-- (IBAction)closeSheet:(id)sender
-{
- [NSApp endSheet:[sender window] returnCode:[sender tag]];
- [[sender window] orderOut:self];
-}
-
-/**
- * Opens the content filter help page in the default browser.
- */
-- (IBAction)showDefaultOperaterHelp:(id)sender
-{
- [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:SPLOCALIZEDURL_CONTENTFILTERHELP]];
+ [filterTableController showFilterTableWindow];
}
#pragma mark -
@@ -3664,29 +3399,14 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
[self setFiltersToRestore:nil];
}
-- (void) setFilterTableData:(NSData*)arcData
+- (NSData*) filterTableData
{
-#ifndef SP_CODA
- if(!arcData) return;
- NSDictionary *filterData = [NSUnarchiver unarchiveObjectWithData:arcData];
- [filterTableData removeAllObjects];
- [filterTableData addEntriesFromDictionary:filterData];
- [filterTableWindow makeKeyAndOrderFront:nil];
- // [filterTableView reloadData];
-#endif
+ return [filterTableController filterTableData];
}
-- (NSData*) filterTableData
+- (void)setFilterTableData:(NSData *)arcData;
{
-#ifndef SP_CODA
- if(![filterTableWindow isVisible]) return nil;
-
- [filterTableView deselectAll:nil];
-
- return [NSArchiver archivedDataWithRootObject:filterTableData];
-#else
- return nil;
-#endif
+ [filterTableController setFilterTableData:arcData];
}
#pragma mark -
@@ -3916,7 +3636,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
// Display table veiew vertical gridlines preference changed
if ([keyPath isEqualToString:SPDisplayTableViewVerticalGridlines]) {
[tableContentView setGridStyleMask:([[change objectForKey:NSKeyValueChangeNewKey] boolValue]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
- [filterTableView setGridStyleMask:([[change objectForKey:NSKeyValueChangeNewKey] boolValue]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
}
// Table font preference changed
else if ([keyPath isEqualToString:SPGlobalResultTableFont]) {
@@ -3982,11 +3701,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
- (NSInteger)numberOfRowsInTableView:(SPCopyTable *)tableView
{
-#ifndef SP_CODA
- if (tableView == filterTableView) {
- return filterTableIsSwapped ? [filterTableData count] : [[[filterTableData objectForKey:@"0"] objectForKey:SPTableContentFilterKey] count];
- }
-#endif
if (tableView == tableContentView) {
return tableRowsCount;
}
@@ -3997,20 +3711,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
- (id)tableView:(SPCopyTable *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
{
NSUInteger columnIndex = [[tableColumn identifier] integerValue];
-#ifndef SP_CODA
- if (tableView == filterTableView) {
- if (filterTableIsSwapped) {
- // First column shows the field names
- if (columnIndex == 0) {
- return [[[NSTableHeaderCell alloc] initTextCell:[[filterTableData objectForKey:[NSNumber numberWithInteger:rowIndex]] objectForKey:@"name"]] autorelease];
- }
-
- return NSArrayObjectAtIndex([[filterTableData objectForKey:[NSNumber numberWithInteger:rowIndex]] objectForKey:SPTableContentFilterKey], columnIndex - 1);
- }
-
- return NSArrayObjectAtIndex([[filterTableData objectForKey:[tableColumn identifier]] objectForKey:SPTableContentFilterKey], rowIndex);
- }
-#endif
if (tableView == tableContentView) {
id value = nil;
@@ -4081,20 +3781,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
{
-#ifndef SP_CODA
- if(tableView == filterTableView) {
- if (filterTableIsSwapped) {
- [[[filterTableData objectForKey:[NSNumber numberWithInteger:rowIndex]] objectForKey:SPTableContentFilterKey] replaceObjectAtIndex:([[tableColumn identifier] integerValue] - 1) withObject:(NSString *)object];
- }
- else {
- [[[filterTableData objectForKey:[tableColumn identifier]] objectForKey:SPTableContentFilterKey] replaceObjectAtIndex:rowIndex withObject:(NSString *)object];
- }
-
- [self updateFilterTableClause:nil];
-
- return;
- }
-#endif
if (tableView == tableContentView) {
NSInteger columnIndex = [[tableColumn identifier] integerValue];
// If the current cell should have been edited in a sheet, do nothing - field closing will have already
@@ -4186,187 +3872,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
#ifndef SP_CODA
/**
- * Escape passed operator for usage as filterTableDefaultOperator.
- */
-- (NSString*)escapeFilterTableDefaultOperator:(NSString *)op
-{
- if (!op) return @"";
-
- NSMutableString *newOp = [[[NSMutableString alloc] initWithCapacity:[op length]] autorelease];
-
- [newOp setString:op];
- [newOp replaceOccurrencesOfRegex:@"%" withString:@"%%"];
- [newOp replaceOccurrencesOfRegex:@"(?<!`)@(?!=`)" withString:@"%@"];
-
- return newOp;
-}
-
-/**
- * Update WHERE clause in filter table window.
- *
- * @param currentValue If currentValue == nil take the data from filterTableData, if currentValue == filterTableSearchAllFields
- * generate a WHERE clause to search in all given fields, if currentValue == a string take this string as table cell data of the
- * currently edited table cell
- */
-- (void)updateFilterTableClause:(id)currentValue
-{
- NSMutableString *clause = [NSMutableString string];
- NSInteger numberOfRows = [self numberOfRowsInTableView:filterTableView];
- NSInteger numberOfCols = [[filterTableView tableColumns] count];
- NSInteger numberOfValues = 0;
- NSRange opRange, defopRange;
-
- BOOL lookInAllFields = NO;
-
- NSString *re1 = @"^\\s*(<[=>]?|>=?|!?=|≠|≤|≥)\\s*(.*?)\\s*$";
- NSString *re2 = @"^\\s*(.*)\\s+(.*?)\\s*$";
-
- NSInteger editedRow = [filterTableView editedRow];
-
- if (currentValue == filterTableSearchAllFields) {
- numberOfRows = 1;
- lookInAllFields = YES;
- }
-
- [filterTableWhereClause setString:@""];
-
- for (NSInteger i = 0; i < numberOfRows; i++)
- {
- numberOfValues = 0;
-
- for (NSInteger anIndex = 0; anIndex < numberOfCols; anIndex++)
- {
- NSString *filterCell = nil;
- NSDictionary *filterCellData = [NSDictionary dictionaryWithDictionary:[filterTableData objectForKey:[NSString stringWithFormat:@"%ld", (long)anIndex]]];
-
- // Take filterTableData
- if (!currentValue) {
- filterCell = NSArrayObjectAtIndex([filterCellData objectForKey:SPTableContentFilterKey], i);
- }
- // Take last edited value to create the OR clause
- else if (lookInAllFields) {
- if (lastEditedFilterTableValue && [lastEditedFilterTableValue length]) {
- filterCell = lastEditedFilterTableValue;
- }
- else {
- [filterTableWhereClause setString:@""];
- [filterTableWhereClause insertText:@""];
- [filterTableWhereClause scrollRangeToVisible:NSMakeRange(0, 0)];
-
- // If live search is set perform filtering
- if ([filterTableLiveSearchCheckbox state] == NSOnState) {
- [self filterTable:filterTableFilterButton];
- }
- }
- }
- // Take value from currently edited table cell
- else if ([currentValue isKindOfClass:[NSString class]]) {
- if (i == editedRow && anIndex == [[NSArrayObjectAtIndex([filterTableView tableColumns], [filterTableView editedColumn]) identifier] integerValue]) {
- filterCell = (NSString*)currentValue;
- }
- else {
- filterCell = NSArrayObjectAtIndex([filterCellData objectForKey:SPTableContentFilterKey], i);
- }
- }
-
- if ([filterCell length]) {
-
- // Recode special operators
- filterCell = [filterCell stringByReplacingOccurrencesOfRegex:@"^\\s*≠" withString:@"!="];
- filterCell = [filterCell stringByReplacingOccurrencesOfRegex:@"^\\s*≤" withString:@"<="];
- filterCell = [filterCell stringByReplacingOccurrencesOfRegex:@"^\\s*≥" withString:@">="];
-
- if (numberOfValues) {
- [clause appendString:(lookInAllFields) ? @" OR " : @" AND "];
- }
-
- NSString *fieldName = [[filterCellData objectForKey:@"name"] backtickQuotedString];
- NSString *filterTableDefaultOperatorWithFieldName = [filterTableDefaultOperator stringByReplacingOccurrencesOfString:@"`@`" withString:fieldName];
-
- opRange = [filterCell rangeOfString:@"`@`"];
- defopRange = [filterTableDefaultOperator rangeOfString:@"`@`"];
-
- // if cell data begins with ' or " treat it as it is
- // by checking if default operator by itself contains a ' or " - if so
- // remove first and if given the last ' or "
- if ([filterCell isMatchedByRegex:@"^\\s*['\"]"]) {
- if ([filterTableDefaultOperator isMatchedByRegex:@"['\"]"]) {
- NSArray *matches = [filterCell arrayOfCaptureComponentsMatchedByRegex:@"^\\s*(['\"])(.*)\\1\\s*$"];
-
- if ([matches count] && [matches = NSArrayObjectAtIndex(matches, 0) count] == 3) {
- [clause appendFormat:[NSString stringWithFormat:@"%%@ %@", filterTableDefaultOperatorWithFieldName], fieldName, NSArrayObjectAtIndex(matches, 2)];
- }
- else {
- matches = [filterCell arrayOfCaptureComponentsMatchedByRegex:@"^\\s*(['\"])(.*)\\s*$"];
-
- if ([matches count] && [matches = NSArrayObjectAtIndex(matches, 0) count] == 3) {
- [clause appendFormat:[NSString stringWithFormat:@"%%@ %@", filterTableDefaultOperatorWithFieldName], fieldName, NSArrayObjectAtIndex(matches, 2)];
- }
- }
- }
- else {
- [clause appendFormat:[NSString stringWithFormat:@"%%@ %@", filterTableDefaultOperatorWithFieldName], fieldName, filterCell];
- }
- }
- // If cell contains the field name placeholder
- else if (opRange.length || defopRange.length) {
- filterCell = [filterCell stringByReplacingOccurrencesOfString:@"`@`" withString:fieldName];
-
- if (defopRange.length) {
- [clause appendFormat:filterTableDefaultOperatorWithFieldName, [filterCell stringByReplacingOccurrencesOfString:@"`@`" withString:fieldName]];
- }
- else {
- [clause appendString:[filterCell stringByReplacingOccurrencesOfString:@"`@`" withString:fieldName]];
- }
- }
- // If cell is equal to NULL
- else if ([filterCell isMatchedByRegex:@"(?i)^\\s*null\\s*$"]) {
- [clause appendFormat:@"%@ IS NULL", fieldName];
- }
- // If cell starts with an operator
- else if ([filterCell isMatchedByRegex:re1]) {
- NSArray *matches = [filterCell arrayOfCaptureComponentsMatchedByRegex:re1];
-
- if ([matches count] && [matches = NSArrayObjectAtIndex(matches, 0) count] == 3) {
- [clause appendFormat:@"%@ %@ %@", fieldName, NSArrayObjectAtIndex(matches, 1), NSArrayObjectAtIndex(matches, 2)];
- }
- }
- // If cell consists of at least two words treat the first as operator and the rest as argument
- else if ([filterCell isMatchedByRegex:re2]) {
- NSArray *matches = [filterCell arrayOfCaptureComponentsMatchedByRegex:re2];
-
- if ([matches count] && [matches = NSArrayObjectAtIndex(matches,0) count] == 3) {
- [clause appendFormat:@"%@ %@ %@", fieldName, [NSArrayObjectAtIndex(matches, 1) uppercaseString], NSArrayObjectAtIndex(matches, 2)];
- }
- }
- // Apply the default operator
- else {
- [clause appendFormat:[NSString stringWithFormat:@"%%@ %@", filterTableDefaultOperatorWithFieldName], fieldName, filterCell];
- }
-
- numberOfValues++;
- }
- }
-
- if (numberOfValues) {
- [clause appendString:@"\nOR\n"];
- }
- }
-
- // Remove last " OR " if any
- [filterTableWhereClause setString:[clause length] > 3 ? [clause substringToIndex:([clause length] - 4)] : @""];
-
- // Update syntax highlighting and uppercasing
- [filterTableWhereClause insertText:@""];
- [filterTableWhereClause scrollRangeToVisible:NSMakeRange(0, 0)];
-
- // If live search is set perform filtering
- if ([filterTableLiveSearchCheckbox state] == NSOnState) {
- [self filterTable:filterTableFilterButton];
- }
-}
-
-/**
* Makes the content filter field have focus by making it the first responder.
*/
- (void)makeContentFilterHaveFocus
@@ -4546,135 +4051,128 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
{
if ([tableDocumentInstance isWorking]) return NO;
-#ifndef SP_CODA
- if (tableView == filterTableView) {
- return (filterTableIsSwapped && [[tableColumn identifier] integerValue] == 0) ? NO : YES;
- }
- else
-#endif
- if (tableView == tableContentView) {
-
- // Nothing is editable while the field editor is running.
- // This guards against a special case where accessibility services might
- // check if a table field is editable while the sheet is running.
- if (fieldEditor) return NO;
+ if (tableView == tableContentView) {
- // Ensure that row is editable since it could contain "(not loaded)" columns together with
- // issue that the table has no primary key
- NSString *wherePart = [NSString stringWithString:[self argumentForRow:[tableContentView selectedRow]]];
+ // Nothing is editable while the field editor is running.
+ // This guards against a special case where accessibility services might
+ // check if a table field is editable while the sheet is running.
+ if (fieldEditor) return NO;
- if (![wherePart length]) return NO;
+ // Ensure that row is editable since it could contain "(not loaded)" columns together with
+ // issue that the table has no primary key
+ NSString *wherePart = [NSString stringWithString:[self argumentForRow:[tableContentView selectedRow]]];
- // If the selected cell hasn't been loaded, load it.
- if ([[tableValues cellDataAtRow:rowIndex column:[[tableColumn identifier] integerValue]] isSPNotLoaded]) {
+ if (![wherePart length]) return NO;
- // Only get the data for the selected column, not all of them
- NSString *query = [NSString stringWithFormat:@"SELECT %@ FROM %@ WHERE %@", [[[tableColumn headerCell] stringValue] backtickQuotedString], [selectedTable backtickQuotedString], wherePart];
+ // If the selected cell hasn't been loaded, load it.
+ if ([[tableValues cellDataAtRow:rowIndex column:[[tableColumn identifier] integerValue]] isSPNotLoaded]) {
- SPMySQLResult *tempResult = [mySQLConnection queryString:query];
+ // Only get the data for the selected column, not all of them
+ NSString *query = [NSString stringWithFormat:@"SELECT %@ FROM %@ WHERE %@", [[[tableColumn headerCell] stringValue] backtickQuotedString], [selectedTable backtickQuotedString], wherePart];
- if (![tempResult numberOfRows]) {
- SPOnewayAlertSheet(
- NSLocalizedString(@"Error", @"error"),
- [tableDocumentInstance parentWindow],
- NSLocalizedString(@"Couldn't load the row. Reload the table to be sure that the row exists and use a primary key for your table.", @"message of panel when loading of row failed")
- );
- return NO;
- }
+ SPMySQLResult *tempResult = [mySQLConnection queryString:query];
- NSArray *tempRow = [tempResult getRowAsArray];
-
- [tableValues replaceObjectInRow:rowIndex column:[[tableContentView tableColumns] indexOfObject:tableColumn] withObject:[tempRow objectAtIndex:0]];
- [tableContentView reloadData];
+ if (![tempResult numberOfRows]) {
+ SPOnewayAlertSheet(
+ NSLocalizedString(@"Error", @"error"),
+ [tableDocumentInstance parentWindow],
+ NSLocalizedString(@"Couldn't load the row. Reload the table to be sure that the row exists and use a primary key for your table.", @"message of panel when loading of row failed")
+ );
+ return NO;
}
- // Retrieve the column definition
- NSDictionary *columnDefinition = [cqColumnDefinition objectAtIndex:[[tableColumn identifier] integerValue]];
+ NSArray *tempRow = [tempResult getRowAsArray];
- // Open the editing sheet if required
- if ([tableContentView shouldUseFieldEditorForRow:rowIndex column:[[tableColumn identifier] integerValue] checkWithLock:NULL]) {
+ [tableValues replaceObjectInRow:rowIndex column:[[tableContentView tableColumns] indexOfObject:tableColumn] withObject:[tempRow objectAtIndex:0]];
+ [tableContentView reloadData];
+ }
- BOOL isBlob = [tableDataInstance columnIsBlobOrText:[[tableColumn headerCell] stringValue]];
+ // Retrieve the column definition
+ NSDictionary *columnDefinition = [cqColumnDefinition objectAtIndex:[[tableColumn identifier] integerValue]];
- // A table is per definition editable
- BOOL isFieldEditable = YES;
+ // Open the editing sheet if required
+ if ([tableContentView shouldUseFieldEditorForRow:rowIndex column:[[tableColumn identifier] integerValue] checkWithLock:NULL]) {
- // Check for Views if field is editable
- if ([tablesListInstance tableType] == SPTableTypeView) {
- NSArray *editStatus = [self fieldEditStatusForRow:rowIndex andColumn:[[tableColumn identifier] integerValue]];
- isFieldEditable = [[editStatus objectAtIndex:0] integerValue] == 1;
- }
+ BOOL isBlob = [tableDataInstance columnIsBlobOrText:[[tableColumn headerCell] stringValue]];
- NSUInteger fieldLength = 0;
- NSString *fieldEncoding = nil;
- BOOL allowNULL = YES;
+ // A table is per definition editable
+ BOOL isFieldEditable = YES;
- NSString *fieldType = [columnDefinition objectForKey:@"type"];
+ // Check for Views if field is editable
+ if ([tablesListInstance tableType] == SPTableTypeView) {
+ NSArray *editStatus = [self fieldEditStatusForRow:rowIndex andColumn:[[tableColumn identifier] integerValue]];
+ isFieldEditable = [[editStatus objectAtIndex:0] integerValue] == 1;
+ }
- if ([columnDefinition objectForKey:@"char_length"]) {
- fieldLength = [[columnDefinition objectForKey:@"char_length"] integerValue];
- }
+ NSUInteger fieldLength = 0;
+ NSString *fieldEncoding = nil;
+ BOOL allowNULL = YES;
- if ([columnDefinition objectForKey:@"null"]) {
- allowNULL = (![[columnDefinition objectForKey:@"null"] integerValue]);
- }
+ NSString *fieldType = [columnDefinition objectForKey:@"type"];
- if ([columnDefinition objectForKey:@"charset_name"] && ![[columnDefinition objectForKey:@"charset_name"] isEqualToString:@"binary"]) {
- fieldEncoding = [columnDefinition objectForKey:@"charset_name"];
- }
+ if ([columnDefinition objectForKey:@"char_length"]) {
+ fieldLength = [[columnDefinition objectForKey:@"char_length"] integerValue];
+ }
- fieldEditor = [[SPFieldEditorController alloc] init];
+ if ([columnDefinition objectForKey:@"null"]) {
+ allowNULL = (![[columnDefinition objectForKey:@"null"] integerValue]);
+ }
- [fieldEditor setEditedFieldInfo:[NSDictionary dictionaryWithObjectsAndKeys:
- [[tableColumn headerCell] stringValue], @"colName",
- [self usedQuery], @"usedQuery",
- @"content", @"tableSource",
- nil]];
+ if ([columnDefinition objectForKey:@"charset_name"] && ![[columnDefinition objectForKey:@"charset_name"] isEqualToString:@"binary"]) {
+ fieldEncoding = [columnDefinition objectForKey:@"charset_name"];
+ }
- [fieldEditor setTextMaxLength:fieldLength];
- [fieldEditor setFieldType:fieldType == nil ? @"" : fieldType];
- [fieldEditor setFieldEncoding:fieldEncoding == nil ? @"" : fieldEncoding];
- [fieldEditor setAllowNULL:allowNULL];
+ fieldEditor = [[SPFieldEditorController alloc] init];
- id cellValue = [tableValues cellDataAtRow:rowIndex column:[[tableColumn identifier] integerValue]];
+ [fieldEditor setEditedFieldInfo:[NSDictionary dictionaryWithObjectsAndKeys:
+ [[tableColumn headerCell] stringValue], @"colName",
+ [self usedQuery], @"usedQuery",
+ @"content", @"tableSource",
+ nil]];
- if ([cellValue isNSNull]) {
- cellValue = [NSString stringWithString:[prefs objectForKey:SPNullValue]];
- }
+ [fieldEditor setTextMaxLength:fieldLength];
+ [fieldEditor setFieldType:fieldType == nil ? @"" : fieldType];
+ [fieldEditor setFieldEncoding:fieldEncoding == nil ? @"" : fieldEncoding];
+ [fieldEditor setAllowNULL:allowNULL];
- if ([self cellValueIsDisplayedAsHexForColumn:[[tableColumn identifier] integerValue]]) {
- [fieldEditor setTextMaxLength:[[self tableView:tableContentView objectValueForTableColumn:tableColumn row:rowIndex] length]];
- isFieldEditable = NO;
- }
+ id cellValue = [tableValues cellDataAtRow:rowIndex column:[[tableColumn identifier] integerValue]];
- NSInteger editedColumn = 0;
+ if ([cellValue isNSNull]) {
+ cellValue = [NSString stringWithString:[prefs objectForKey:SPNullValue]];
+ }
- for (NSTableColumn* col in [tableContentView tableColumns])
- {
- if ([[col identifier] isEqualToString:[tableColumn identifier]]) break;
+ if ([self cellValueIsDisplayedAsHexForColumn:[[tableColumn identifier] integerValue]]) {
+ [fieldEditor setTextMaxLength:[[self tableView:tableContentView objectValueForTableColumn:tableColumn row:rowIndex] length]];
+ isFieldEditable = NO;
+ }
- editedColumn++;
- }
+ NSInteger editedColumn = 0;
- [fieldEditor editWithObject:cellValue
- fieldName:[[tableColumn headerCell] stringValue]
- usingEncoding:[mySQLConnection stringEncoding]
- isObjectBlob:isBlob
- isEditable:isFieldEditable
- withWindow:[tableDocumentInstance parentWindow]
- sender:self
- contextInfo:[NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithInteger:rowIndex], @"rowIndex",
- [NSNumber numberWithInteger:editedColumn], @"columnIndex",
- [NSNumber numberWithBool:isFieldEditable], @"isFieldEditable",
- nil]];
+ for (NSTableColumn* col in [tableContentView tableColumns])
+ {
+ if ([[col identifier] isEqualToString:[tableColumn identifier]]) break;
- return NO;
+ editedColumn++;
}
- return YES;
+ [fieldEditor editWithObject:cellValue
+ fieldName:[[tableColumn headerCell] stringValue]
+ usingEncoding:[mySQLConnection stringEncoding]
+ isObjectBlob:isBlob
+ isEditable:isFieldEditable
+ withWindow:[tableDocumentInstance parentWindow]
+ sender:self
+ contextInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInteger:rowIndex], @"rowIndex",
+ [NSNumber numberWithInteger:editedColumn], @"columnIndex",
+ [NSNumber numberWithBool:isFieldEditable], @"isFieldEditable",
+ nil]];
+
+ return NO;
}
+ return YES;
+ }
+
return YES;
}
@@ -4714,13 +4212,7 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
*/
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)rowIndex
{
-#ifndef SP_CODA
- if (tableView == filterTableView) {
- return YES;
- }
- else
-#endif
- return tableView == tableContentView ? tableRowsSelectable : YES;
+ return tableView == tableContentView ? tableRowsSelectable : YES;
}
/**
@@ -4775,76 +4267,62 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
*/
- (void)tableView:(SPCopyTable *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
{
-#ifndef SP_CODA
- if (tableView == filterTableView) {
- if (filterTableIsSwapped && [[tableColumn identifier] integerValue] == 0) {
- [cell setDrawsBackground:YES];
- [cell setBackgroundColor:lightGrayColor];
- }
- else {
- [cell setDrawsBackground:NO];
- }
+ if (tableView == tableContentView) {
- return;
- }
- else
-#endif
- if (tableView == tableContentView) {
+ if (![cell respondsToSelector:@selector(setTextColor:)]) return;
- if (![cell respondsToSelector:@selector(setTextColor:)]) return;
+ BOOL cellIsNullOrUnloaded = NO;
+ BOOL cellIsLinkCell = [cell isMemberOfClass:[SPTextAndLinkCell class]];
- BOOL cellIsNullOrUnloaded = NO;
- BOOL cellIsLinkCell = [cell isMemberOfClass:[SPTextAndLinkCell class]];
+ NSUInteger columnIndex = [[tableColumn identifier] integerValue];
- NSUInteger columnIndex = [[tableColumn identifier] integerValue];
+ // If user wants to edit 'cell' set text color to black and return to avoid
+ // writing in gray if value was NULL
+ if ([tableView editedColumn] != -1
+ && [tableView editedRow] == rowIndex
+ && (NSUInteger)[[NSArrayObjectAtIndex([tableView tableColumns], [tableView editedColumn]) identifier] integerValue] == columnIndex) {
+ [cell setTextColor:blackColor];
+ if (cellIsLinkCell) [cell setLinkActive:NO];
+ return;
+ }
- // If user wants to edit 'cell' set text color to black and return to avoid
- // writing in gray if value was NULL
- if ([tableView editedColumn] != -1
- && [tableView editedRow] == rowIndex
- && (NSUInteger)[[NSArrayObjectAtIndex([tableView tableColumns], [tableView editedColumn]) identifier] integerValue] == columnIndex) {
- [cell setTextColor:blackColor];
- if (cellIsLinkCell) [cell setLinkActive:NO];
- return;
+ // While the table is being loaded, additional validation is required - data
+ // locks must be used to avoid crashes, and indexes higher than the available
+ // rows or columns may be requested. Use gray to indicate loading in these cases.
+ if (isWorking) {
+ pthread_mutex_lock(&tableValuesLock);
+
+ if (rowIndex < (NSInteger)tableRowsCount && columnIndex < [tableValues columnCount]) {
+ cellIsNullOrUnloaded = [tableValues cellIsNullOrUnloadedAtRow:rowIndex column:columnIndex];
}
- // While the table is being loaded, additional validation is required - data
- // locks must be used to avoid crashes, and indexes higher than the available
- // rows or columns may be requested. Use gray to indicate loading in these cases.
- if (isWorking) {
- pthread_mutex_lock(&tableValuesLock);
+ pthread_mutex_unlock(&tableValuesLock);
+ }
+ else {
+ cellIsNullOrUnloaded = [tableValues cellIsNullOrUnloadedAtRow:rowIndex column:columnIndex];
+ }
- if (rowIndex < (NSInteger)tableRowsCount && columnIndex < [tableValues columnCount]) {
- cellIsNullOrUnloaded = [tableValues cellIsNullOrUnloadedAtRow:rowIndex column:columnIndex];
- }
+ if (cellIsNullOrUnloaded) {
+ [cell setTextColor:rowIndex == [tableContentView selectedRow] ? whiteColor : lightGrayColor];
+ }
+ else {
+ [cell setTextColor:blackColor];
- pthread_mutex_unlock(&tableValuesLock);
- }
- else {
- cellIsNullOrUnloaded = [tableValues cellIsNullOrUnloadedAtRow:rowIndex column:columnIndex];
+ if ([self cellValueIsDisplayedAsHexForColumn:[[tableColumn identifier] integerValue]]) {
+ [cell setTextColor:rowIndex == [tableContentView selectedRow] ? whiteColor : blueColor];
}
+ }
- if (cellIsNullOrUnloaded) {
- [cell setTextColor:rowIndex == [tableContentView selectedRow] ? whiteColor : lightGrayColor];
+ // Disable link arrows for the currently editing row and for any NULL or unloaded cells
+ if (cellIsLinkCell) {
+ if (cellIsNullOrUnloaded || [tableView editedRow] == rowIndex) {
+ [cell setLinkActive:NO];
}
else {
- [cell setTextColor:blackColor];
-
- if ([self cellValueIsDisplayedAsHexForColumn:[[tableColumn identifier] integerValue]]) {
- [cell setTextColor:rowIndex == [tableContentView selectedRow] ? whiteColor : blueColor];
- }
- }
-
- // Disable link arrows for the currently editing row and for any NULL or unloaded cells
- if (cellIsLinkCell) {
- if (cellIsNullOrUnloaded || [tableView editedRow] == rowIndex) {
- [cell setLinkActive:NO];
- }
- else {
- [cell setLinkActive:YES];
- }
+ [cell setLinkActive:YES];
}
}
+ }
}
#ifndef SP_CODA
@@ -4857,10 +4335,7 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
*/
- (NSString *)tableView:(NSTableView *)tableView toolTipForCell:(id)aCell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row mouseLocation:(NSPoint)mouseLocation
{
- if (tableView == filterTableView) {
- return nil;
- }
- else if (tableView == tableContentView) {
+ if (tableView == tableContentView) {
if ([[aCell stringValue] length] < 2 || [tableDocumentInstance isWorking]) return nil;
@@ -4923,12 +4398,11 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
// Show the cell string value as tooltip (including line breaks and tabs)
// by using the cell's font
[SPTooltip showWithObject:[aCell stringValue]
- atLocation:pos
- ofType:@"text"
- displayOptions:[NSDictionary dictionaryWithObjectsAndKeys:
- [[aCell font] familyName], @"fontname",
- [NSString stringWithFormat:@"%f",[[aCell font] pointSize]], @"fontsize",
- nil]];
+ atLocation:pos
+ ofType:@"text"
+ displayOptions:[NSDictionary dictionaryWithObjectsAndKeys:[[aCell font] familyName], @"fontname",
+ [NSString stringWithFormat:@"%f", [[aCell font] pointSize]], @"fontsize",
+ nil]];
return nil;
}
@@ -4968,24 +4442,6 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
return YES;
}
-- (void)controlTextDidChange:(NSNotification *)notification
-{
-#ifndef SP_CODA
- if ([notification object] == filterTableView) {
-
- NSString *string = [[[[notification userInfo] objectForKey:@"NSFieldEditor"] textStorage] string];
-
- if (string && [string length]) {
- if (lastEditedFilterTableValue) [lastEditedFilterTableValue release];
-
- lastEditedFilterTableValue = [[NSString stringWithString:string] retain];
- }
-
- [self updateFilterTableClause:string];
- }
-#endif
-}
-
/**
* If the user selected a table cell which is a blob field and tried to edit it
* cancel the inline edit, display the field editor sheet instead for editing
@@ -5128,13 +4584,10 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
SPClear(dataColumns);
SPClear(oldRow);
#ifndef SP_CODA
- for (id retainedObject in nibObjectsToRelease) [retainedObject release];
+ for (id retainedObject in nibObjectsToRelease) [retainedObject release];
SPClear(nibObjectsToRelease);
SPClear(paginationPopover);
- SPClear(filterTableData);
- if (lastEditedFilterTableValue) SPClear(lastEditedFilterTableValue);
- if (filterTableDefaultOperator) SPClear(filterTableDefaultOperator);
#endif
if (selectedTable) SPClear(selectedTable);
if (keys) SPClear(keys);
diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj
index 409f85b4..79afe4e7 100644
--- a/sequel-pro.xcodeproj/project.pbxproj
+++ b/sequel-pro.xcodeproj/project.pbxproj
@@ -391,6 +391,7 @@
58FEF57E0F3B4E9700518E8E /* SPTableData.m in Sources */ = {isa = PBXBuildFile; fileRef = 58FEF57D0F3B4E9700518E8E /* SPTableData.m */; };
73F70A961E4E547500636550 /* SPJSONFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 73F70A951E4E547500636550 /* SPJSONFormatter.m */; };
8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; };
+ 9BE76F2886901784E4FD2321 /* SPFilterTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BE76A3D5C9830E2F7738770 /* SPFilterTableController.m */; };
B51D6B9E114C310C0074704E /* toolbar-switch-to-table-triggers.png in Resources */ = {isa = PBXBuildFile; fileRef = B51D6B9D114C310C0074704E /* toolbar-switch-to-table-triggers.png */; };
B52460D70F8EF92300171639 /* SPArrayAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B52460D40F8EF92300171639 /* SPArrayAdditions.m */; };
B52460D80F8EF92300171639 /* SPTextViewAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B52460D60F8EF92300171639 /* SPTextViewAdditions.m */; };
@@ -411,6 +412,7 @@
B5E2C5FA0F2353B5007446E0 /* table-property.png in Resources */ = {isa = PBXBuildFile; fileRef = B5E2C5F90F2353B5007446E0 /* table-property.png */; };
B5E92F190F75B2D100012500 /* ExportDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = B5E92F170F75B2D100012500 /* ExportDialog.xib */; };
B5E92F1C0F75B2E800012500 /* SPExportController.m in Sources */ = {isa = PBXBuildFile; fileRef = B5E92F1B0F75B2E800012500 /* SPExportController.m */; };
+ BAC6BAF920A0D22400247837 /* FilterTableWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = BAC6BAF720A0D22400247837 /* FilterTableWindow.xib */; };
BC01BCCF104024BE006BDEE7 /* SPEncodingPopupAccessory.m in Sources */ = {isa = PBXBuildFile; fileRef = BC01BCCE104024BE006BDEE7 /* SPEncodingPopupAccessory.m */; };
BC05F1C5101241DF008A97F8 /* YRKSpinningProgressIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = BC05F1C4101241DF008A97F8 /* YRKSpinningProgressIndicator.m */; };
BC09D7DE12A786FB0030DB64 /* cancel-clicked-highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = BC09D7D812A786FB0030DB64 /* cancel-clicked-highlighted.png */; };
@@ -1127,6 +1129,8 @@
73F70A941E4E547500636550 /* SPJSONFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPJSONFormatter.h; sourceTree = "<group>"; };
73F70A951E4E547500636550 /* SPJSONFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPJSONFormatter.m; sourceTree = "<group>"; };
8D15AC370486D014006FF6A4 /* Sequel Pro.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Sequel Pro.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9BE76A3D5C9830E2F7738770 /* SPFilterTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPFilterTableController.m; sourceTree = "<group>"; };
+ 9BE76F9BF9BDA2921CDD05AF /* SPFilterTableController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPFilterTableController.h; sourceTree = "<group>"; };
B51D6B9D114C310C0074704E /* toolbar-switch-to-table-triggers.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "toolbar-switch-to-table-triggers.png"; sourceTree = "<group>"; };
B52460D30F8EF92300171639 /* SPArrayAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPArrayAdditions.h; sourceTree = "<group>"; };
B52460D40F8EF92300171639 /* SPArrayAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPArrayAdditions.m; sourceTree = "<group>"; };
@@ -1153,6 +1157,7 @@
B5E92F1A0F75B2E800012500 /* SPExportController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPExportController.h; sourceTree = "<group>"; };
B5E92F1B0F75B2E800012500 /* SPExportController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPExportController.m; sourceTree = "<group>"; };
B5EAC0FC0EC87FF900CC579C /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
+ BAC6BAF820A0D22400247837 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/FilterTableWindow.xib; sourceTree = "<group>"; };
BC01BCCD104024BE006BDEE7 /* SPEncodingPopupAccessory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPEncodingPopupAccessory.h; sourceTree = "<group>"; };
BC01BCCE104024BE006BDEE7 /* SPEncodingPopupAccessory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPEncodingPopupAccessory.m; sourceTree = "<group>"; };
BC05F1C3101241DF008A97F8 /* YRKSpinningProgressIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YRKSpinningProgressIndicator.h; sourceTree = "<group>"; };
@@ -1557,6 +1562,8 @@
1713C73D140D88D400CFD461 /* Query Controller */,
17381853151FB29C0078FFE2 /* User Manager */,
17846B9D170C95D800414499 /* Process List */,
+ 9BE76A3D5C9830E2F7738770 /* SPFilterTableController.m */,
+ 9BE76F9BF9BDA2921CDD05AF /* SPFilterTableController.h */,
);
name = "Subview Controllers";
sourceTree = "<group>";
@@ -2158,6 +2165,7 @@
BCCBD7FA104408B000D4C50A /* SaveSPFAccessory.xib */,
B58DA7390FF8BB9E00FDDACD /* SSHQuestionDialog.xib */,
4D90B7A0101E0D1500D116A1 /* UserManagerView.xib */,
+ BAC6BAF720A0D22400247837 /* FilterTableWindow.xib */,
);
path = Interfaces;
sourceTree = "<group>";
@@ -2847,6 +2855,7 @@
BC2C8E220FA8C2DB008468C7 /* SPMySQLHelpTemplate.html in Resources */,
384582C40FB95FF800DDACB6 /* func-small.png in Resources */,
384582C70FB9603600DDACB6 /* proc-small.png in Resources */,
+ BAC6BAF920A0D22400247837 /* FilterTableWindow.xib in Resources */,
177E792E0FCB54EC00E9E122 /* database-small.png in Resources */,
177E792F0FCB54EC00E9E122 /* dummy-small.png in Resources */,
B58DA73C0FF8BBA500FDDACD /* PrintAccessory.xib in Resources */,
@@ -3267,6 +3276,7 @@
50E217B318174246009D3580 /* SPColorSelectorView.m in Sources */,
50E217B618174280009D3580 /* SPFavoriteColorSupport.m in Sources */,
1A564F74237E2E4958CA593A /* SPPillAttachmentCell.m in Sources */,
+ 9BE76F2886901784E4FD2321 /* SPFilterTableController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3542,6 +3552,14 @@
name = ExportDialog.xib;
sourceTree = "<group>";
};
+ BAC6BAF720A0D22400247837 /* FilterTableWindow.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ BAC6BAF820A0D22400247837 /* English */,
+ );
+ name = FilterTableWindow.xib;
+ sourceTree = "<group>";
+ };
BC30C00F111C98BD002701C9 /* DataMigrationDialog.xib */ = {
isa = PBXVariantGroup;
children = (