Proper editing functionality + bugfix sortindex consistency
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1968E0AE14B8E8A90E194980 /* PyHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 1968EF7567E06D2A5BB3481A /* PyHandler.m */; };
|
||||
544B011A2114B41200386E5C /* FeedEdit.m in Sources */ = {isa = PBXBuildFile; fileRef = 544B01192114B41200386E5C /* FeedEdit.m */; };
|
||||
544B011A2114B41200386E5C /* ModalSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 544B01192114B41200386E5C /* ModalSheet.m */; };
|
||||
544B011D2114EE9100386E5C /* AppHook.m in Sources */ = {isa = PBXBuildFile; fileRef = 544B011C2114EE9100386E5C /* AppHook.m */; };
|
||||
544FBD4521064AEB008A260C /* Python.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 544FBD4421064AEB008A260C /* Python.framework */; };
|
||||
544FBD4721064B2F008A260C /* getFeed.py in Resources */ = {isa = PBXBuildFile; fileRef = 544FBD4621064B2F008A260C /* getFeed.py */; };
|
||||
@@ -25,8 +25,8 @@
|
||||
/* Begin PBXFileReference section */
|
||||
1968E7919BAA36F042FCB717 /* PyHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PyHandler.h; sourceTree = "<group>"; };
|
||||
1968EF7567E06D2A5BB3481A /* PyHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PyHandler.m; sourceTree = "<group>"; };
|
||||
544B01182114B41200386E5C /* FeedEdit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FeedEdit.h; sourceTree = "<group>"; };
|
||||
544B01192114B41200386E5C /* FeedEdit.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FeedEdit.m; sourceTree = "<group>"; };
|
||||
544B01182114B41200386E5C /* ModalSheet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ModalSheet.h; sourceTree = "<group>"; };
|
||||
544B01192114B41200386E5C /* ModalSheet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ModalSheet.m; sourceTree = "<group>"; };
|
||||
544B011B2114EE9100386E5C /* AppHook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppHook.h; sourceTree = "<group>"; };
|
||||
544B011C2114EE9100386E5C /* AppHook.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppHook.m; sourceTree = "<group>"; };
|
||||
544FBD4421064AEB008A260C /* Python.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Python.framework; path = System/Library/Frameworks/Python.framework; sourceTree = SDKROOT; };
|
||||
@@ -106,8 +106,8 @@
|
||||
54ACC29421061E270020715F /* NewsController.m */,
|
||||
54ACC29621061FBA0020715F /* Preferences.h */,
|
||||
54ACC29721061FBA0020715F /* Preferences.m */,
|
||||
544B01182114B41200386E5C /* FeedEdit.h */,
|
||||
544B01192114B41200386E5C /* FeedEdit.m */,
|
||||
544B01182114B41200386E5C /* ModalSheet.h */,
|
||||
544B01192114B41200386E5C /* ModalSheet.m */,
|
||||
54ACC28521061B3C0020715F /* Assets.xcassets */,
|
||||
54ACC28721061B3C0020715F /* Main.xib */,
|
||||
54ACC28A21061B3C0020715F /* Info.plist */,
|
||||
@@ -202,7 +202,7 @@
|
||||
54ACC29521061E270020715F /* NewsController.m in Sources */,
|
||||
54ACC28C21061B3C0020715F /* main.m in Sources */,
|
||||
54ACC28121061B3B0020715F /* AppDelegate.m in Sources */,
|
||||
544B011A2114B41200386E5C /* FeedEdit.m in Sources */,
|
||||
544B011A2114B41200386E5C /* ModalSheet.m in Sources */,
|
||||
54ACC29821061FBA0020715F /* Preferences.m in Sources */,
|
||||
1968E0AE14B8E8A90E194980 /* PyHandler.m in Sources */,
|
||||
);
|
||||
|
||||
@@ -43,15 +43,20 @@ static NSEventModifierFlags fnKeyFlags = NSEventModifierFlagShift | NSEventModif
|
||||
case 'w': if ([self sendAction:@selector(performClose:) to:nil from:self]) return; break;
|
||||
}
|
||||
} else if (flags == (NSEventModifierFlagCommand | NSEventModifierFlagShift)) {
|
||||
if (key == 'z') {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wundeclared-selector"
|
||||
if (key == 'z') {
|
||||
if ([self sendAction:@selector(redo:) to:nil from:self])
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (key == 13 || key == 3) { // Enter / Return key
|
||||
if ([self sendAction:@selector(enterPressed:) to:nil from:self])
|
||||
return;
|
||||
}
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
}
|
||||
[super sendEvent:event];
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
<outlet property="statusMenu" destination="tDc-nD-HS2" id="eHw-32-GGa"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||
<menu id="tDc-nD-HS2">
|
||||
<items>
|
||||
<menuItem title="Pause Updates" id="D7r-Vb-9eO">
|
||||
@@ -59,6 +58,8 @@
|
||||
<binding destination="Voe-Tx-rLC" name="managedObjectContext" keyPath="self.persistentContainer.viewContext" id="Q1f-VN-9qq"/>
|
||||
<outlet property="outlineView" destination="hKk-G1-1po" id="Z4y-uD-Zse"/>
|
||||
<outlet property="preferencesWindow" destination="ai3-RW-O8g" id="cNF-TI-ups"/>
|
||||
<outlet property="viewModalEditFeed" destination="QwK-my-u5w" id="gpw-6X-48E"/>
|
||||
<outlet property="viewModalEditGroup" destination="cQF-4Y-gsL" id="NJF-jl-dhg"/>
|
||||
</connections>
|
||||
</treeController>
|
||||
<window title="baRSS Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="prefWindow" animationBehavior="default" tabbingMode="disallowed" id="ai3-RW-O8g" userLabel="Preferences" customClass="Preferences">
|
||||
@@ -72,14 +73,14 @@
|
||||
</view>
|
||||
<toolbar key="toolbar" implicitIdentifier="5B23E7E6-13E5-4910-875D-2E3EA566F38B" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconAndLabel" sizeMode="regular" id="wLj-fD-HpE">
|
||||
<allowedToolbarItems>
|
||||
<toolbarItem implicitItemIdentifier="AF4483E3-0457-47B7-AE52-AC11B1545455" explicitItemIdentifier="preferencesTabGeneral" label="General" paletteLabel="General" tag="-1" image="NSPreferencesGeneral" selectable="YES" id="0qP-ah-ojT">
|
||||
<toolbarItem implicitItemIdentifier="AF4483E3-0457-47B7-AE52-AC11B1545455" explicitItemIdentifier="tabGeneral" label="General" paletteLabel="General" tag="-1" image="NSPreferencesGeneral" selectable="YES" id="0qP-ah-ojT">
|
||||
<connections>
|
||||
<action selector="tabGeneralClicked:" target="ai3-RW-O8g" id="OiJ-PY-QCu"/>
|
||||
<action selector="tabClicked:" target="ai3-RW-O8g" id="ebr-gX-OQB"/>
|
||||
</connections>
|
||||
</toolbarItem>
|
||||
<toolbarItem implicitItemIdentifier="E8527558-3D5F-4B79-99E4-675C1557D10B" explicitItemIdentifier="preferencesTabFeeds" label="Feeds" paletteLabel="Feeds" tag="-1" image="NSUserAccounts" selectable="YES" id="Av5-VA-zps">
|
||||
<toolbarItem implicitItemIdentifier="E8527558-3D5F-4B79-99E4-675C1557D10B" explicitItemIdentifier="tabFeeds" label="Feeds" paletteLabel="Feeds" tag="-1" image="NSUserAccounts" selectable="YES" id="Av5-VA-zps">
|
||||
<connections>
|
||||
<action selector="tabFeedsClicked:" target="ai3-RW-O8g" id="l5x-nd-qBx"/>
|
||||
<action selector="tabClicked:" target="ai3-RW-O8g" id="hhx-TR-X5c"/>
|
||||
</connections>
|
||||
</toolbarItem>
|
||||
</allowedToolbarItems>
|
||||
@@ -89,7 +90,7 @@
|
||||
</defaultToolbarItems>
|
||||
</toolbar>
|
||||
<connections>
|
||||
<outlet property="feedDetailSheet" destination="6yF-Ii-jhG" id="ozt-yn-eEM"/>
|
||||
<outlet property="modalSheet" destination="oXi-oJ-x37" id="EWx-yQ-jsK"/>
|
||||
<outlet property="newsController" destination="1oZ-Uo-mIu" id="1HA-Vz-PBK"/>
|
||||
<outlet property="viewFeeds" destination="EwH-fT-yW8" id="aBH-fR-foa"/>
|
||||
<outlet property="viewGeneral" destination="8H4-sI-Ub8" id="PS7-gG-GJs"/>
|
||||
@@ -321,7 +322,7 @@
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn identifier="" editable="NO" width="262" minWidth="40" maxWidth="42000" id="Lb1-9n-wlc">
|
||||
<tableColumn identifier="NameColumn" editable="NO" width="262" minWidth="40" maxWidth="42000" id="Lb1-9n-wlc">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Name">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -334,25 +335,22 @@
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="cellFeedConfigName" id="xPj-mA-zCd">
|
||||
<tableCellView identifier="cellFeed" id="xPj-mA-zCd" userLabel="Feed">
|
||||
<rect key="frame" x="1" y="1" width="262" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZkQ-CQ-77k">
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZkQ-CQ-77k" userLabel="img">
|
||||
<rect key="frame" x="3" y="0.0" width="17" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="6xE-Sq-YVt"/>
|
||||
</imageView>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="v0D-kY-dKT">
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="v0D-kY-dKT" userLabel="str">
|
||||
<rect key="frame" x="25" y="0.0" width="237" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="AQH-6L-dw6">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<connections>
|
||||
<binding destination="xPj-mA-zCd" name="value" keyPath="objectValue.name" id="0Dx-uS-rnx"/>
|
||||
</connections>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
@@ -361,11 +359,11 @@
|
||||
<outlet property="textField" destination="v0D-kY-dKT" id="gFH-Fi-20f"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<tableCellView identifier="cellFeedConfigSeperator" id="IkM-wJ-Az7" userLabel="Separator">
|
||||
<tableCellView identifier="cellSeparator" id="IkM-wJ-Az7" userLabel="Separator">
|
||||
<rect key="frame" x="1" y="20" width="262" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mlO-VE-655" userLabel="img" customClass="Separator">
|
||||
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mlO-VE-655" userLabel="img" customClass="DrawSeparator">
|
||||
<rect key="frame" x="3" y="0.0" width="256" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</customView>
|
||||
@@ -373,7 +371,7 @@
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
<connections>
|
||||
<binding destination="1oZ-Uo-mIu" name="value" keyPath="arrangedObjects" id="Ghy-7M-Gx2">
|
||||
<binding destination="1oZ-Uo-mIu" name="value" keyPath="arrangedObjects" id="aPh-ik-Vma">
|
||||
<dictionary key="options">
|
||||
<bool key="NSConditionallySetsEditable" value="YES"/>
|
||||
<bool key="NSCreatesSortDescriptor" value="NO"/>
|
||||
@@ -381,7 +379,7 @@
|
||||
</binding>
|
||||
</connections>
|
||||
</tableColumn>
|
||||
<tableColumn identifier="cellFeedConfigRefresh" editable="NO" width="50" minWidth="40" maxWidth="1000" id="8st-OH-BXG">
|
||||
<tableColumn identifier="RefreshColumn" editable="NO" width="50" minWidth="40" maxWidth="1000" id="8st-OH-BXG">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Refresh">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -393,7 +391,7 @@
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="cellFeedConfigRefresh" id="tSf-op-fUB" userLabel="cellView">
|
||||
<tableCellView identifier="cellRefresh" id="tSf-op-fUB" userLabel="cellView">
|
||||
<rect key="frame" x="266" y="1" width="50" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
@@ -404,9 +402,6 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<connections>
|
||||
<binding destination="tSf-op-fUB" name="value" keyPath="objectValue.refresh" id="Eqe-4f-Qns"/>
|
||||
</connections>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
@@ -416,7 +411,7 @@
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
<connections>
|
||||
<binding destination="1oZ-Uo-mIu" name="value" keyPath="arrangedObjects" id="hf4-eT-K3p">
|
||||
<binding destination="1oZ-Uo-mIu" name="value" keyPath="arrangedObjects" id="qDC-Su-t66">
|
||||
<dictionary key="options">
|
||||
<bool key="NSConditionallySetsEditable" value="YES"/>
|
||||
<bool key="NSCreatesSortDescriptor" value="NO"/>
|
||||
@@ -426,7 +421,7 @@
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<action trigger="doubleAction" selector="presentModalFeedProperties:" target="1oZ-Uo-mIu" id="zNP-kQ-Xmh"/>
|
||||
<action trigger="doubleAction" selector="doubleClickOutlineView:" target="1oZ-Uo-mIu" id="v7z-dG-bmC"/>
|
||||
<outlet property="dataSource" destination="1oZ-Uo-mIu" id="sch-o5-yEm"/>
|
||||
<outlet property="delegate" destination="1oZ-Uo-mIu" id="Nye-dQ-vdy"/>
|
||||
</connections>
|
||||
@@ -456,7 +451,7 @@
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="addFeed:" target="1oZ-Uo-mIu" id="jX0-xl-p0f"/>
|
||||
<action selector="add:" target="1oZ-Uo-mIu" id="Lw4-zq-eUW"/>
|
||||
<binding destination="1oZ-Uo-mIu" name="enabled" keyPath="canInsert" id="1xq-Nj-Acq"/>
|
||||
</connections>
|
||||
</button>
|
||||
@@ -471,7 +466,7 @@ CA
|
||||
</string>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="remove:" target="1oZ-Uo-mIu" id="mph-g8-8J0"/>
|
||||
<action selector="remove:" target="1oZ-Uo-mIu" id="7nP-Sj-Hap"/>
|
||||
<binding destination="1oZ-Uo-mIu" name="enabled" keyPath="canRemove" id="9oY-fm-uq0"/>
|
||||
</connections>
|
||||
</button>
|
||||
@@ -511,66 +506,19 @@ CA
|
||||
<point key="canvasLocation" x="350" y="903.5"/>
|
||||
</customView>
|
||||
<userDefaultsController representsSharedInstance="YES" id="K8S-BW-Na6"/>
|
||||
<window title="Feed Detail Sheet" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="formFeedDetail" animationBehavior="default" id="6yF-Ii-jhG" customClass="FeedEdit">
|
||||
<window title="Modal Sheet" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="modalSheet" animationBehavior="default" id="oXi-oJ-x37" customClass="ModalSheet">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<rect key="contentRect" x="131" y="159" width="400" height="153"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="131" y="159" width="332" height="145"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="878"/>
|
||||
<value key="minSize" type="size" width="400" height="153"/>
|
||||
<value key="maxSize" type="size" width="1200" height="153"/>
|
||||
<view key="contentView" id="bH3-c8-m3D">
|
||||
<rect key="frame" x="0.0" y="0.0" width="400" height="153"/>
|
||||
<view key="contentView" id="m8f-7v-xRV">
|
||||
<rect key="frame" x="0.0" y="0.0" width="332" height="145"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="u2j-52-0kN">
|
||||
<rect key="frame" x="18" y="114" width="103" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="URL" id="FDr-0e-igw">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9nh-vY-v6W">
|
||||
<rect key="frame" x="127" y="112" width="253" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="https://example.org/feed.rss" drawsBackground="YES" usesSingleLineMode="YES" id="VSm-J7-qAA">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Znc-BK-dhw">
|
||||
<rect key="frame" x="18" y="85" width="103" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Name" id="Uda-8X-onH">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5uB-Zy-4u6">
|
||||
<rect key="frame" x="127" y="83" width="253" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="Example Title" drawsBackground="YES" usesSingleLineMode="YES" id="vzt-hb-cGT">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sMQ-B7-WTo">
|
||||
<rect key="frame" x="127" y="54" width="86" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="30" drawsBackground="YES" usesSingleLineMode="YES" id="bNw-iS-Gfz">
|
||||
<customFormatter key="formatter" id="NEE-2h-FN9" customClass="StrictUIntFormatter"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Az1-ZL-15b">
|
||||
<rect key="frame" x="232" y="13" width="82" height="32"/>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lHM-1e-0h3">
|
||||
<rect key="frame" x="164" y="13" width="82" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="V93-O8-bjm">
|
||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="DO7-Wp-Cq3">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
@@ -578,64 +526,148 @@ Gw
|
||||
</string>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="didTapCancelButton:" target="6yF-Ii-jhG" id="uS5-n0-iZ3"/>
|
||||
<action selector="didTapCancelButton:" target="oXi-oJ-x37" id="anY-ux-Ie4"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CRz-wU-u6m">
|
||||
<rect key="frame" x="314" y="13" width="72" height="32"/>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xUx-US-sER">
|
||||
<rect key="frame" x="246" y="13" width="72" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Done" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="fdr-rD-bgC">
|
||||
<buttonCell key="cell" type="push" title="Done" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="wdX-J6-h3E">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
DQ
|
||||
</string>
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="didTapDoneButton:" target="6yF-Ii-jhG" id="vK2-Ou-z3b"/>
|
||||
<action selector="didTapDoneButton:" target="oXi-oJ-x37" id="umh-ON-tK6"/>
|
||||
</connections>
|
||||
</button>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="FYV-ch-Bjd" userLabel="TimeUnit">
|
||||
<rect key="frame" x="219" y="51" width="127" height="26"/>
|
||||
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ow4-Dc-KCa">
|
||||
<rect key="frame" x="20" y="53" width="292" height="72"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</customView>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="content" destination="ow4-Dc-KCa" id="fom-bt-A3N"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-407" y="551.5"/>
|
||||
</window>
|
||||
<customView id="QwK-my-u5w" customClass="ModalFeedEdit">
|
||||
<rect key="frame" x="0.0" y="0.0" width="323" height="79"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Td3-u0-pGV" userLabel="URL Label">
|
||||
<rect key="frame" x="-2" y="60" width="103" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Minutes" bezelStyle="rounded" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" autoenablesItems="NO" selectedItem="7DG-HF-41v" id="54G-6B-9Vg">
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="URL" id="VB0-b9-Imn">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eWg-Kh-Bvb">
|
||||
<rect key="frame" x="107" y="58" width="216" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="https://example.org/feed.rss" drawsBackground="YES" usesSingleLineMode="YES" id="udH-RT-BoZ">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="H9R-jT-1k4" userLabel="Name Label">
|
||||
<rect key="frame" x="-2" y="31" width="103" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Name" id="paa-p9-Gef">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XJj-pu-bly">
|
||||
<rect key="frame" x="107" y="29" width="216" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="Example Title" drawsBackground="YES" usesSingleLineMode="YES" id="tu7-Bi-83I">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lVa-3A-b87" userLabel="Refresh Label">
|
||||
<rect key="frame" x="-2" y="2" width="103" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Refresh" id="Sb5-pD-amO">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vXf-Zz-0rI">
|
||||
<rect key="frame" x="107" y="0.0" width="86" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="30" drawsBackground="YES" usesSingleLineMode="YES" id="C8B-JP-s9v">
|
||||
<customFormatter key="formatter" id="OLW-GD-byx" customClass="StrictUIntFormatter"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gYP-CV-xZj" userLabel="TimeUnit">
|
||||
<rect key="frame" x="199" y="-3" width="127" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Minutes" bezelStyle="rounded" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" autoenablesItems="NO" altersStateOfSelectedItem="NO" selectedItem="b1E-eP-OOD" id="XWW-TF-FD4">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" showsStateColumn="NO" autoenablesItems="NO" id="FA5-Wc-aKF">
|
||||
<menu key="menu" showsStateColumn="NO" autoenablesItems="NO" id="zrI-Up-teS">
|
||||
<items>
|
||||
<menuItem title="Seconds" id="ObP-NX-RUr">
|
||||
<menuItem title="Seconds" keyEquivalent="s" id="NV5-6S-mc1">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Minutes" state="on" id="7DG-HF-41v">
|
||||
<menuItem title="Minutes" keyEquivalent="m" id="b1E-eP-OOD">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hours" id="buP-XT-lMO">
|
||||
<menuItem title="Hours" keyEquivalent="h" id="ZLd-ga-MiY">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Days" id="wJ7-Ui-a4q">
|
||||
<menuItem title="Days" keyEquivalent="d" id="IGV-5p-cG7">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Weeks" id="Py4-7n-CXD">
|
||||
<menuItem title="Weeks" keyEquivalent="w" id="PyN-Fp-lrI">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hlP-VB-yeu">
|
||||
<rect key="frame" x="18" y="56" width="103" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Refresh" id="c0W-IR-MMR">
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="refreshNum" destination="vXf-Zz-0rI" id="rUP-Fl-ejj"/>
|
||||
<outlet property="refreshUnit" destination="gYP-CV-xZj" id="ufL-Lt-ad0"/>
|
||||
<outlet property="title" destination="XJj-pu-bly" id="csa-JH-2s8"/>
|
||||
<outlet property="url" destination="eWg-Kh-Bvb" id="SKN-kr-avo"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-421.5" y="779.5"/>
|
||||
</customView>
|
||||
<customView id="cQF-4Y-gsL" customClass="ModalGroupEdit">
|
||||
<rect key="frame" x="0.0" y="0.0" width="260" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jb1-Bk-KcD">
|
||||
<rect key="frame" x="0.0" y="0.0" width="260" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="Group Name" placeholderString="Group Name" drawsBackground="YES" usesSingleLineMode="YES" id="gDe-xz-pxK">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="20" y="1225.5"/>
|
||||
</window>
|
||||
<connections>
|
||||
<outlet property="title" destination="Jb1-Bk-KcD" id="aht-3z-H7U"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-407" y="891"/>
|
||||
</customView>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSActionTemplate" width="14" height="14"/>
|
||||
|
||||
@@ -12,12 +12,16 @@
|
||||
<attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<relationship name="config" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="FeedConfig" inverseName="feed" inverseEntity="FeedConfig" syncable="YES"/>
|
||||
<relationship name="items" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="FeedItem" inverseName="feed" inverseEntity="FeedItem" syncable="YES"/>
|
||||
<fetchedProperty name="tags" optional="YES" syncable="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="Feed" predicateString="(SELF.tags.feedItem=$FETCH_SOURCE.items)"/>
|
||||
</fetchedProperty>
|
||||
</entity>
|
||||
<entity name="FeedConfig" representedClassName="FeedConfig" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="refresh" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="refreshNum" optional="YES" attributeType="Integer 32" usesScalarValueType="YES" syncable="YES"/>
|
||||
<attribute name="refreshUnit" optional="YES" attributeType="Integer 16" usesScalarValueType="YES" customClassName="NSUInteger" syncable="YES"/>
|
||||
<attribute name="sortIndex" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
|
||||
<attribute name="type" optional="YES" attributeType="Integer 16" defaultValueString="1" usesScalarValueType="YES" syncable="YES"/>
|
||||
<attribute name="type" optional="YES" attributeType="Integer 16" usesScalarValueType="YES" syncable="YES"/>
|
||||
<attribute name="url" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<relationship name="children" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="FeedConfig" inverseName="parent" inverseEntity="FeedConfig" syncable="YES"/>
|
||||
<relationship name="feed" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="Feed" inverseName="config" inverseEntity="Feed" syncable="YES"/>
|
||||
@@ -38,8 +42,8 @@
|
||||
<relationship name="feedItem" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="FeedItem" inverseName="tags" inverseEntity="FeedItem" syncable="YES"/>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="Feed" positionX="-209" positionY="-3" width="128" height="210"/>
|
||||
<element name="FeedConfig" positionX="-20" positionY="-126" width="128" height="165"/>
|
||||
<element name="Feed" positionX="-209" positionY="-3" width="128" height="239"/>
|
||||
<element name="FeedConfig" positionX="-20" positionY="-126" width="128" height="180"/>
|
||||
<element name="FeedItem" positionX="-20" positionY="81" width="128" height="165"/>
|
||||
<element name="FeedTag" positionX="187" positionY="171" width="128" height="75"/>
|
||||
</elements>
|
||||
|
||||
@@ -22,6 +22,29 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface FeedEdit : NSWindow
|
||||
|
||||
@interface ModalSheet : NSWindow
|
||||
- (void)setFormContent:(NSView *)subcontent;
|
||||
@end
|
||||
|
||||
|
||||
@interface ModalFeedEdit : NSView
|
||||
@property (weak) IBOutlet NSTextField *url;
|
||||
@property (weak) IBOutlet NSTextField *title;
|
||||
@property (weak) IBOutlet NSTextField *refreshNum;
|
||||
@property (weak) IBOutlet NSPopUpButton *refreshUnit;
|
||||
- (void)setDefaultValues;
|
||||
- (void)setURL:(NSString*)url name:(NSString*)name refreshNum:(int32_t)num unit:(int16_t)unit;
|
||||
+ (NSString*)stringForRefreshNum:(int32_t)num unit:(int16_t)unit;
|
||||
@end
|
||||
|
||||
|
||||
@interface ModalGroupEdit : NSView
|
||||
@property (weak) IBOutlet NSTextField *title;
|
||||
- (void)setDefaultValues;
|
||||
- (void)setGroupName:(NSString*)name;
|
||||
@end
|
||||
|
||||
|
||||
@interface StrictUIntFormatter : NSFormatter
|
||||
@end
|
||||
|
||||
@@ -20,25 +20,80 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#import "FeedEdit.h"
|
||||
#import "ModalSheet.h"
|
||||
|
||||
@implementation FeedEdit
|
||||
#define BETWEEN(x,min,max) (x < min ? min : x > max ? max : x)
|
||||
|
||||
|
||||
#pragma mark - ModalSheet
|
||||
|
||||
@interface ModalSheet()
|
||||
@property (weak) IBOutlet NSView *content;
|
||||
@end
|
||||
|
||||
@implementation ModalSheet
|
||||
- (void)setFormContent:(NSView *)subcontent {
|
||||
[self.content.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
|
||||
CGFloat heightDiff = subcontent.frame.size.height - self.content.frame.size.height;
|
||||
NSRect oldFrame = self.frame;
|
||||
oldFrame.size.height += heightDiff;
|
||||
[self setFrame:oldFrame display:NO];
|
||||
|
||||
[subcontent setFrameSize:NSMakeSize(self.content.frame.size.width, subcontent.frame.size.height)];
|
||||
[self.content addSubview:subcontent];
|
||||
[self recalculateKeyViewLoop];
|
||||
|
||||
self.minSize = NSMakeSize(323 + 40, self.frame.size.height);
|
||||
self.maxSize = NSMakeSize(1200, self.frame.size.height);
|
||||
}
|
||||
- (IBAction)didTapDoneButton:(id)sender {
|
||||
[self.parentWindow endSheet:self returnCode:NSModalResponseOK];
|
||||
[self.sheetParent endSheet:self returnCode:NSModalResponseOK];
|
||||
}
|
||||
|
||||
- (IBAction)didTapCancelButton:(id)sender {
|
||||
[self.parentWindow endSheet:self returnCode:NSModalResponseAbort];
|
||||
[self.sheetParent endSheet:self returnCode:NSModalResponseAbort];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - ModalFeedEdit
|
||||
|
||||
@interface StrictUIntFormatter : NSFormatter
|
||||
|
||||
@implementation ModalFeedEdit
|
||||
- (void)setDefaultValues {
|
||||
self.url.stringValue = @"";
|
||||
self.title.stringValue = @"";
|
||||
self.refreshNum.intValue = 30;
|
||||
[self.refreshUnit selectItemAtIndex:1];
|
||||
}
|
||||
- (void)setURL:(NSString*)url name:(NSString*)name refreshNum:(int32_t)num unit:(int16_t)unit {
|
||||
self.url.objectValue = url;
|
||||
self.title.objectValue = name;
|
||||
self.refreshNum.intValue = num;
|
||||
[self.refreshUnit selectItemAtIndex:BETWEEN(unit, 0, self.refreshUnit.numberOfItems - 1)];
|
||||
}
|
||||
+ (NSString*)stringForRefreshNum:(int32_t)num unit:(int16_t)unit {
|
||||
return [NSString stringWithFormat:@"%d%c", num, [@"smhdw" characterAtIndex:(NSUInteger)BETWEEN(unit, 0, 4)]];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - ModalGroupEdit
|
||||
|
||||
|
||||
@implementation ModalGroupEdit
|
||||
- (void)setDefaultValues {
|
||||
self.title.stringValue = @"New Group";
|
||||
}
|
||||
- (void)setGroupName:(NSString*)name {
|
||||
self.title.objectValue = name;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - StrictUIntFormatter
|
||||
|
||||
|
||||
@implementation StrictUIntFormatter
|
||||
- (NSString *)stringForObjectValue:(id)obj {
|
||||
return [NSString stringWithFormat:@"%d", [[NSString stringWithFormat:@"%@", obj] intValue]];
|
||||
@@ -28,4 +28,5 @@
|
||||
- (IBAction)addSeparator:(NSButton *)sender;
|
||||
|
||||
- (NSString*)copyDescriptionOfSelectedItems;
|
||||
- (void)openModalForSelection;
|
||||
@end
|
||||
|
||||
@@ -24,9 +24,12 @@
|
||||
#import "PyHandler.h"
|
||||
#import "Preferences.h"
|
||||
#import "DBv1+CoreDataModel.h"
|
||||
#import "ModalSheet.h"
|
||||
|
||||
@interface NewsController ()
|
||||
@property (weak) IBOutlet Preferences *preferencesWindow;
|
||||
@property (weak) IBOutlet ModalFeedEdit *viewModalEditFeed;
|
||||
@property (weak) IBOutlet ModalGroupEdit *viewModalEditGroup;
|
||||
@property (weak) IBOutlet NSOutlineView *outlineView;
|
||||
|
||||
@property (strong) NSArray<NSTreeNode*> *currentlyDraggedNodes;
|
||||
@@ -35,7 +38,7 @@
|
||||
@implementation NewsController
|
||||
|
||||
// Declare a string constant for the drag type - to be used when writing and retrieving pasteboard data...
|
||||
static NSString *dragNodeType = @"baRSS-feed-type";
|
||||
static NSString *dragNodeType = @"baRSS-feed-drag";
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[super awakeFromNib];
|
||||
@@ -45,17 +48,24 @@ static NSString *dragNodeType = @"baRSS-feed-type";
|
||||
}
|
||||
|
||||
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
|
||||
// owner is nil to prohibit repeated awakeFromNib calls
|
||||
NSTableCellView *cellView = [self.outlineView makeViewWithIdentifier:tableColumn.identifier owner:nil];
|
||||
if (cellView)
|
||||
return cellView; // is a refresh cell
|
||||
|
||||
FeedConfig *f = [(NSTreeNode*)item representedObject];
|
||||
if (f.type == 2) { // Seperator
|
||||
return [self.outlineView makeViewWithIdentifier:@"cellFeedConfigSeperator" owner:nil];
|
||||
bool isSeperator = (f.type == 2);
|
||||
bool isRefreshColumn = [tableColumn.identifier isEqualToString:@"RefreshColumn"];
|
||||
|
||||
NSString *cellIdent = (isRefreshColumn ? @"cellRefresh" : (isSeperator ? @"cellSeparator" : @"cellFeed"));
|
||||
// owner is nil to prohibit repeated awakeFromNib calls
|
||||
NSTableCellView *cellView = [self.outlineView makeViewWithIdentifier:cellIdent owner:nil];
|
||||
|
||||
if (isRefreshColumn) {
|
||||
cellView.textField.stringValue = (f.type != 1 ? @"" : [ModalFeedEdit stringForRefreshNum:f.refreshNum unit:f.refreshUnit]);
|
||||
} else if (isSeperator) {
|
||||
return cellView; // the refresh cell is already skipped with the above if condition
|
||||
} else {
|
||||
cellView.textField.objectValue = f.name;
|
||||
cellView.imageView.image = (f.type == 0 ? [NSImage imageNamed:NSImageNameFolder] : nil);
|
||||
// TODO: load icon or show default rss icon
|
||||
}
|
||||
cellView = [self.outlineView makeViewWithIdentifier:@"cellFeedConfigName" owner:nil];
|
||||
cellView.imageView.image = [NSImage imageNamed:NSImageNameFolder];
|
||||
cellView.textField.textColor = (f.refreshNum == 0 ? [NSColor disabledControlTextColor] : [NSColor controlTextColor]);
|
||||
return cellView;
|
||||
}
|
||||
|
||||
@@ -99,39 +109,17 @@ static NSString *dragNodeType = @"baRSS-feed-type";
|
||||
NSLog(@"all unread");
|
||||
}
|
||||
|
||||
- (IBAction)presentModalFeedProperties:(id)sender {
|
||||
self.preferencesWindow.feedDetailSheet.parentWindow = self.preferencesWindow;
|
||||
[self.preferencesWindow beginSheet:self.preferencesWindow.feedDetailSheet completionHandler:^(NSModalResponse returnCode) {
|
||||
NSLog(@"%ld", (long)returnCode);
|
||||
}];
|
||||
// if ([sender isKindOfClass:[NSOutlineView class]]) {
|
||||
// NSOutlineView *ov = sender;
|
||||
// if (ov.clickedRow == -1)
|
||||
// return; // ignore clicks on column headers and where no row was selected
|
||||
//
|
||||
// id vop = [ov itemAtRow:ov.clickedRow];
|
||||
// NSLog(@"%@", vop);
|
||||
// }
|
||||
#pragma mark - Insert & Edit Feed Items
|
||||
|
||||
- (IBAction)addFeed:(id)sender {
|
||||
[self showModalForFeedConfig:nil isGroupEdit:NO];
|
||||
}
|
||||
|
||||
- (IBAction)addFeed:(NSButton *)sender {
|
||||
[self.managedObjectContext.undoManager beginUndoGrouping];
|
||||
FeedConfig *nf = [self insertSortedItemAtSelection];
|
||||
nf.type = 1;
|
||||
nf.name = [NSString stringWithFormat:@"%@", [NSDate date]];
|
||||
nf.refresh = @"42s";
|
||||
[self.managedObjectContext.undoManager endUndoGrouping];
|
||||
- (IBAction)addGroup:(id)sender {
|
||||
[self showModalForFeedConfig:nil isGroupEdit:YES];
|
||||
}
|
||||
|
||||
- (IBAction)addGroup:(NSButton *)sender {
|
||||
[self.managedObjectContext.undoManager beginUndoGrouping];
|
||||
FeedConfig *g = [self insertSortedItemAtSelection];
|
||||
g.name = @"Group";
|
||||
g.type = 0;
|
||||
[self.managedObjectContext.undoManager endUndoGrouping];
|
||||
}
|
||||
|
||||
- (IBAction)addSeparator:(NSButton *)sender {
|
||||
- (IBAction)addSeparator:(id)sender {
|
||||
[self.managedObjectContext.undoManager beginUndoGrouping];
|
||||
FeedConfig *sp = [self insertSortedItemAtSelection];
|
||||
sp.name = @"---";
|
||||
@@ -139,6 +127,86 @@ static NSString *dragNodeType = @"baRSS-feed-type";
|
||||
[self.managedObjectContext.undoManager endUndoGrouping];
|
||||
}
|
||||
|
||||
- (void)remove:(id)sender {
|
||||
[self.managedObjectContext.undoManager beginUndoGrouping];
|
||||
for (NSIndexPath *path in self.selectionIndexPaths)
|
||||
[self incrementIndicesBy:-1 forSubsequentNodes:path];
|
||||
[super remove:sender];
|
||||
[self.managedObjectContext.undoManager endUndoGrouping];
|
||||
}
|
||||
|
||||
- (IBAction)doubleClickOutlineView:(NSOutlineView*)sender {
|
||||
if (sender.clickedRow == -1)
|
||||
return; // ignore clicks on column headers and where no row was selected
|
||||
|
||||
FeedConfig *fc = [(NSTreeNode*)[sender itemAtRow:sender.clickedRow] representedObject];
|
||||
[self showModalForFeedConfig:fc isGroupEdit:YES]; // yes will be overwritten anyway
|
||||
}
|
||||
|
||||
- (void)openModalForSelection {
|
||||
[self showModalForFeedConfig:self.selectedObjects.firstObject isGroupEdit:YES]; // yes will be overwritten anyway
|
||||
}
|
||||
|
||||
- (void)showModalForFeedConfig:(FeedConfig*)obj isGroupEdit:(bool)group {
|
||||
bool existingItem = [obj isKindOfClass:[FeedConfig class]];
|
||||
if (existingItem) {
|
||||
if (obj.type == 2) return; // Separator
|
||||
group = (obj.type == 0);
|
||||
if (group) [self.viewModalEditGroup setGroupName:obj.name];
|
||||
else [self.viewModalEditFeed setURL:obj.url name:obj.name refreshNum:obj.refreshNum unit:obj.refreshUnit];
|
||||
} else {
|
||||
if (group) [self.viewModalEditGroup setDefaultValues];
|
||||
else [self.viewModalEditFeed setDefaultValues];
|
||||
}
|
||||
NSView *content = (group ? self.viewModalEditGroup : self.viewModalEditFeed);
|
||||
[self.preferencesWindow presentModal:content completion:^(NSModalResponse returnCode) {
|
||||
if (returnCode == NSModalResponseOK) {
|
||||
[self.managedObjectContext.undoManager beginUndoGrouping];
|
||||
FeedConfig *item = obj;
|
||||
if (!existingItem) { // create new item
|
||||
item = [self insertSortedItemAtSelection];
|
||||
item.type = (group ? 0 : 1);
|
||||
}
|
||||
|
||||
if (group) {
|
||||
item.name = self.viewModalEditGroup.title.stringValue;
|
||||
} else {
|
||||
item.name = self.viewModalEditFeed.title.stringValue;
|
||||
item.url = self.viewModalEditFeed.url.stringValue;
|
||||
item.refreshNum = self.viewModalEditFeed.refreshNum.intValue;
|
||||
item.refreshUnit = (int16_t)self.viewModalEditFeed.refreshUnit.indexOfSelectedItem;
|
||||
}
|
||||
[self.managedObjectContext.undoManager endUndoGrouping];
|
||||
[self rearrangeObjects];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (FeedConfig*)insertSortedItemAtSelection {
|
||||
NSIndexPath *selectedIndex = [self selectionIndexPath];
|
||||
NSIndexPath *insertIndex = selectedIndex;
|
||||
|
||||
FeedConfig *selected = [[[self arrangedObjects] descendantNodeAtIndexPath:selectedIndex] representedObject];
|
||||
NSUInteger lastIndex = selected.children.count;
|
||||
bool groupSelected = (selected.type == 0);
|
||||
|
||||
if (!groupSelected) {
|
||||
lastIndex = (NSUInteger)selected.sortIndex + 1; // insert after selection
|
||||
insertIndex = [insertIndex indexPathByRemovingLastIndex];
|
||||
[self incrementIndicesBy:+1 forSubsequentNodes:selectedIndex];
|
||||
--selected.sortIndex; // insert after selection
|
||||
}
|
||||
|
||||
FeedConfig *newItem = [[FeedConfig alloc] initWithEntity:FeedConfig.entity insertIntoManagedObjectContext:self.managedObjectContext];
|
||||
[self insertObject:newItem atArrangedObjectIndexPath:[insertIndex indexPathByAddingIndex:lastIndex]];
|
||||
// First insert, then parent, else troubles
|
||||
newItem.sortIndex = (int32_t)lastIndex;
|
||||
newItem.parent = (groupSelected ? selected : selected.parent);
|
||||
return newItem;
|
||||
}
|
||||
|
||||
#pragma mark - Import & Export of Data
|
||||
|
||||
- (NSString*)copyDescriptionOfSelectedItems {
|
||||
NSMutableString *str = [[NSMutableString alloc] init];
|
||||
for (FeedConfig *item in self.selectedObjects) {
|
||||
@@ -157,30 +225,13 @@ static NSString *dragNodeType = @"baRSS-feed-type";
|
||||
switch (obj.type) {
|
||||
case 0: [str appendFormat:@"%@:\n", obj.name]; break; // Group
|
||||
case 2: [str appendString:@"-------------\n"]; break; // Separator
|
||||
default: [str appendFormat:@"%@ (%@) - %@\n", obj.name, obj.url, obj.refresh];
|
||||
default: [str appendFormat:@"%@ (%@) - %@\n", obj.name, obj.url, [ModalFeedEdit stringForRefreshNum:obj.refreshNum unit:obj.refreshUnit]];
|
||||
}
|
||||
for (FeedConfig *child in obj.children) {
|
||||
[self traverseChildren:child appendString:str indentation:indent + 1];
|
||||
}
|
||||
}
|
||||
|
||||
- (FeedConfig*)insertSortedItemAtSelection {
|
||||
FeedConfig *selected = [[[self arrangedObjects] descendantNodeAtIndexPath:[self selectionIndexPath]] representedObject];
|
||||
if (selected.type != 0) { // other than group
|
||||
[self incrementIndicesBy:+1 forSubsequentNodes:[self selectionIndexPath]];
|
||||
}
|
||||
FeedConfig *newItem = [[FeedConfig alloc] initWithEntity:FeedConfig.entity insertIntoManagedObjectContext:self.managedObjectContext];
|
||||
if (selected.type == 0) { // a group
|
||||
newItem.sortIndex = (int32_t)selected.children.count;
|
||||
newItem.parent = selected;
|
||||
} else {
|
||||
newItem.sortIndex = selected.sortIndex;
|
||||
newItem.parent = selected.parent;
|
||||
--selected.sortIndex; // was increased before the new item is inserted
|
||||
}
|
||||
return newItem;
|
||||
}
|
||||
|
||||
- (void)incrementIndicesBy:(int)val forSubsequentNodes:(NSIndexPath*)path {
|
||||
NSIndexPath *parentPath = [path indexPathByRemovingLastIndex];
|
||||
NSTreeNode *root = [self arrangedObjects];
|
||||
@@ -272,11 +323,11 @@ static NSString *dragNodeType = @"baRSS-feed-type";
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Drawings on Screen
|
||||
|
||||
@interface Separator : NSView
|
||||
@end
|
||||
@interface DrawSeparator : NSView @end
|
||||
|
||||
@implementation Separator
|
||||
@implementation DrawSeparator
|
||||
- (void)drawRect:(NSRect)dirtyRect {
|
||||
[super drawRect:dirtyRect];
|
||||
NSGradient *grdnt = [[NSGradient alloc] initWithStartingColor:[NSColor darkGrayColor] endingColor:[[NSColor darkGrayColor] colorWithAlphaComponent:0.0]];
|
||||
|
||||
@@ -22,7 +22,10 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface Preferences : NSWindow
|
||||
@property (weak) IBOutlet NSWindow *feedDetailSheet;
|
||||
@class ModalSheet;
|
||||
|
||||
@interface Preferences : NSWindow
|
||||
@property (weak) IBOutlet ModalSheet *modalSheet;
|
||||
|
||||
- (void)presentModal:(NSView*)view completion:(void (^ __nullable)(NSModalResponse returnCode))handler;
|
||||
@end
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#import "Preferences.h"
|
||||
#import "NewsController.h"
|
||||
#import "ModalSheet.h"
|
||||
|
||||
@interface Preferences ()
|
||||
@property (weak) IBOutlet NSView *viewGeneral;
|
||||
@@ -33,36 +34,62 @@
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[super awakeFromNib];
|
||||
if (self.contentView.subviews.count == 0) {
|
||||
self.contentView = self.viewGeneral;
|
||||
self.toolbar.selectedItemIdentifier = self.toolbar.items.firstObject.itemIdentifier;
|
||||
}
|
||||
NSUInteger idx = (NSUInteger)[[NSUserDefaults standardUserDefaults] integerForKey:@"preferencesTab"];
|
||||
if (idx >= self.toolbar.items.count)
|
||||
idx = 0;
|
||||
[self tabClicked:self.toolbar.items[idx]];
|
||||
}
|
||||
|
||||
- (IBAction)tabGeneralClicked:(NSToolbarItem *)sender {
|
||||
- (IBAction)tabClicked:(NSToolbarItem *)sender {
|
||||
self.contentView = nil;
|
||||
if ([sender.itemIdentifier isEqualToString:@"tabGeneral"])
|
||||
self.contentView = self.viewGeneral;
|
||||
}
|
||||
|
||||
- (IBAction)tabFeedsClicked:(NSToolbarItem *)sender {
|
||||
else if ([sender.itemIdentifier isEqualToString:@"tabFeeds"])
|
||||
self.contentView = self.viewFeeds;
|
||||
|
||||
self.toolbar.selectedItemIdentifier = sender.itemIdentifier;
|
||||
[self recalculateKeyViewLoop];
|
||||
[self setInitialFirstResponder:self.contentView];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:(NSInteger)[self.toolbar.items indexOfObject:sender]
|
||||
forKey:@"preferencesTab"];
|
||||
}
|
||||
|
||||
- (void)undo:(id)sender {
|
||||
if (self.contentView == self.viewFeeds) {
|
||||
[self.newsController.managedObjectContext.undoManager undo];
|
||||
[self.newsController rearrangeObjects]; // update the ordering
|
||||
}
|
||||
[self.newsController rearrangeObjects]; // update ordering
|
||||
}
|
||||
|
||||
- (void)redo:(id)sender {
|
||||
if (self.contentView == self.viewFeeds) {
|
||||
[self.newsController.managedObjectContext.undoManager redo];
|
||||
[self.newsController rearrangeObjects]; // update the ordering
|
||||
}
|
||||
[self.newsController rearrangeObjects]; // update ordering
|
||||
}
|
||||
|
||||
- (void)copy:(id)sender {
|
||||
[self.newsController copyDescriptionOfSelectedItems];
|
||||
}
|
||||
|
||||
- (void)enterPressed:(id)sender {
|
||||
[self.newsController openModalForSelection];
|
||||
}
|
||||
|
||||
- (BOOL)respondsToSelector:(SEL)aSelector {
|
||||
bool isFeedView = (self.contentView == self.viewFeeds) && !self.attachedSheet;
|
||||
// Only if 'Feeds' Tab is selected & no open modal sheet & NSOutlineView has focus
|
||||
if (aSelector == @selector(enterPressed:) || aSelector == @selector(copy:)) {
|
||||
bool outlineHasFocus = [[self firstResponder] isKindOfClass:[NSOutlineView class]];
|
||||
return isFeedView && outlineHasFocus && (self.newsController.selectedNodes.count > 0);
|
||||
} else if (aSelector == @selector(undo:)) {
|
||||
return isFeedView && [self.newsController.managedObjectContext.undoManager canUndo];
|
||||
} else if (aSelector == @selector(redo:)) {
|
||||
return isFeedView && [self.newsController.managedObjectContext.undoManager canRedo];
|
||||
}
|
||||
return [super respondsToSelector:aSelector];
|
||||
}
|
||||
|
||||
- (void)presentModal:(NSView*)view completion:(void (^ __nullable)(NSModalResponse returnCode))handler {
|
||||
[self.modalSheet setFormContent:view];
|
||||
[self beginSheet:self.modalSheet completionHandler:handler];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user