diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/components.api ubuntu-ui-toolkit-0.1.46+14.04.20131118/components.api --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/components.api 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/components.api 2013-11-18 17:13:10.000000000 +0000 @@ -207,6 +207,7 @@ modules/Ubuntu/Components/TabBar.qml StyledItem property Item tabsItem + property ListModel model property bool selectionMode property bool alwaysSelectionMode property bool animate @@ -216,9 +217,13 @@ readonly property Tab selectedTab readonly property Item currentPage property TabBar tabBar - property internal __tabs default property list tabChildren + readonly property int count signal modelChanged() + function addTab(title, component, params) + function insertTab(index, title, component, params) + function moveTab(from, to) + function removeTab(index) modules/Ubuntu/Components/TextArea.qml StyledItem property bool highlighted diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/debian/changelog ubuntu-ui-toolkit-0.1.46+14.04.20131118/debian/changelog --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/debian/changelog 2013-11-18 17:16:15.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/debian/changelog 2013-11-18 17:16:15.000000000 +0000 @@ -1,3 +1,29 @@ +ubuntu-ui-toolkit (0.1.46+14.04.20131118-0ubuntu1) trusty; urgency=low + + [ Zsombor Egri ] + * Support for dynamically inserting/moving/removing tabs in Tabs. . + (LP: #1124071) + + [ Leo Arias ] + * Fixes for swipe_to_delete on autopilot list items emulator: Take + into account items without confirmation. Take into account items + that are destroyed on removal. (LP: #1245651, #1249221) + + [ Albert Astals ] + * InverseMouseArea: Do not filter events if disabled. + + [ Robert Bruce Park ] + * Support both Python 2 and 3 in the autopilot tests. + + [ Christian Dywan ] + * Track magic window with a property signal instead of defining it. + (LP: #1251436) + + [ Ubuntu daily release ] + * Automatic snapshot from revision 837 + + -- Ubuntu daily release Mon, 18 Nov 2013 17:13:33 +0000 + ubuntu-ui-toolkit (0.1.46+14.04.20131108.4-0ubuntu1) trusty; urgency=low [ Robert Bruce Park ] diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/OrientationHelper.qml ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/OrientationHelper.qml --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/OrientationHelper.qml 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/OrientationHelper.qml 2013-11-18 17:13:10.000000000 +0000 @@ -91,21 +91,34 @@ Component.onCompleted: orientationTransition.enabled = transitionEnabled - /*! - Technically 'window' is defined by QML automatically however this can - happen very late. We define it here so there's no race condition. - */ - Window { - id: window + Object { + id: internal + + /*! + 'window' is defined by QML between startup and showing on the screen. + There is no signal for when it becomes available and re-declaring it is not safe. + + http://qt-project.org/doc/qt-5.1/qtqml/qml-qtqml2-qt.html + http://qt-project.org/doc/qt-5.1/qtquick/qmlmodule-qtquick-window2-qtquick-window-2.html + */ + property bool windowActive: typeof window != 'undefined' + + /*! + Report the current orientation of the application via QWindow::contentOrientation. + http://qt-project.org/doc/qt-5.0/qtgui/qwindow.html#contentOrientation-prop + */ + function applyOrientation() { + if (windowActive) + window.contentOrientation = Screen.orientation + } + + onWindowActiveChanged: applyOrientation() } /*! \internal - - Report the current orientation of the application via QWindow::contentOrientation. - http://qt-project.org/doc/qt-5.0/qtgui/qwindow.html#contentOrientation-prop */ - onOrientationAngleChanged: window.contentOrientation = Screen.orientation + onOrientationAngleChanged: internal.applyOrientation() Item { id: stateWrapper diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/Tab.qml ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/Tab.qml --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/Tab.qml 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/Tab.qml 2013-11-18 17:13:10.000000000 +0000 @@ -87,6 +87,30 @@ property alias __protected: internal QtObject { id: internal + /* + Specifies the index of the Tab in Tabs. + */ property int index: -1 + + /* + Specifies whether the Tab has already been inserted in Tabs model or not. + Pre-declared tabs are added one by one automatically before Tabs component + completion, therefore we need this flag to exclude adding those Tab elements + again which were already added. + */ + property bool inserted: false + + /* + Specifies whether the Tab was created dynamically or not. A dynamically created + Tab is destroyed upon removal. + */ + property bool dynamic: false + + /* + This flag is used by the Tabs to determine whether the pre-declared Tab was removed + from the Tabs model or not. The flag guards adding back pre-declared tabs upon Tabs + component stack (children) change. + */ + property bool removedFromTabs: false } } diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/TabBar.qml ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/TabBar.qml --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/TabBar.qml 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/TabBar.qml 2013-11-18 17:13:10.000000000 +0000 @@ -40,6 +40,17 @@ property Item tabsItem /*! + The model containing the tabs to be controlled by the TabBar. The tabs are + visualized by the style, displaying controlling elements based on the data + specified by the roles. The default style mandates the existence of either + the \b title or \b tab role, but different styles may require to have other + roles (e.g. image, color). The order the role existence is checked is also + determined by the style component, Default style checks the existence of the + \b tab role first, and if not defined will use the \b title role. + */ + property ListModel model + + /*! An inactive tab bar only displays the currently selected tab, and an active tab bar can be interacted with to select a tab. */ diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/Tabs.qml ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/Tabs.qml --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/Tabs.qml 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/Tabs.qml 2013-11-18 17:13:10.000000000 +0000 @@ -155,14 +155,14 @@ The first tab is 0, and -1 means that no tab is selected. The initial value is 0 if Tabs has contents, or -1 otherwise. */ - property int selectedTabIndex: tabs.__tabs.length > 0 ? 0 : -1 + property int selectedTabIndex: tabsModel.count > 0 ? 0 : -1 /*! \preliminary The currently selected tab. */ - readonly property Tab selectedTab: (selectedTabIndex < 0) || (__tabs.length <= selectedTabIndex) ? - null : __tabs[selectedTabIndex] + readonly property Tab selectedTab: (selectedTabIndex < 0) || (tabsModel.count <= selectedTabIndex) ? + null : tabsModel.get(selectedTabIndex).tab /*! The page of the currently selected tab. @@ -175,20 +175,21 @@ */ property TabBar tabBar: TabBar { tabsItem: tabs + model: tabsModel visible: tabs.active } /*! - \internal - Used by the style to create the tabs header. - */ - property alias __tabs: tabsModel.tabList - - /*! Children are placed in a separate item that has functionality to extract the Tab items. \qmlproperty list tabChildren */ - default property alias tabChildren: tabsModel.children + default property alias tabChildren: tabStack.data + + /*! + \qmlproperty int count + Contains the number of tabs in the Tabs component. + */ + readonly property alias count: tabsModel.count /*! Used by the tabs style to update the tabs header with the titles of all the tabs. @@ -198,40 +199,187 @@ signal modelChanged() /*! + Appends a Tab dynamically to the list of tabs. The \a title specifies the + title of the Tab. The \a component can be either a Component, a URL to + the Tab component to be loaded or an instance of a pre-declared tab that + has been previously removed. The Tab's title will be replaced with the given + \a title, unless if the given value is empty string or undefined. The optional + \a params defines parameters passed to the Tab. + Returns the instance of the added Tab. + */ + function addTab(title, component, params) { + return insertTab(count, title, component, params); + } + + /*! + Inserts a Tab at the given index. If the \a index is less or equal than 0, + the Tab will be added to the front, and to the end of the tab stack if the + \a index is greater than \l count. \a title, \a component and \a params + are used in the same way as in \l addTab(). Returns the instance of the + inserted Tab. + */ + function insertTab(index, title, component, params) { + // check if the given component is a Tab instance + var tab = null; + if (component && component.hasOwnProperty("page") && component.hasOwnProperty("__protected")) { + // dynamically added components are destroyed upon removal, so + // in case we get a Tab as parameter, we can only have a predeclared one + // therefore we simply restore the default state of the removedFromTabs property + // and return the instance + if (!component.__protected.removedFromTabs) { + // exit if the Tab is not removed + return null; + } + + component.__protected.removedFromTabs = false; + tab = component; + } else { + var tabComponent = null; + if (typeof component === "string") { + tabComponent = Qt.createComponent(component); + } else { + tabComponent = component; + } + if (tabComponent.status === Component.Error) { + console.error(tabComponent.errorString()); + return null; + } + tab = tabComponent.createObject(); + tab.__protected.dynamic = true; + } + + // fix title + if (title !== undefined && title !== "") { + tab.title = title; + } + + // insert the created tab into the model + index = MathUtils.clamp(index, 0, count); + tab.__protected.inserted = true; + tab.__protected.index = index; + tabsModel.insert(index, tabsModel.listModel(tab)); + tabsModel.reindex(index); + tab.parent = tabStack; + if (tabs.selectedTabIndex >= index) { + // move the selected index to the next index + tabs.selectedTabIndex += 1; + } else { + tabs.modelChanged(); + } + return tab; + } + + /*! + Moves the tab from the given \a from position to the position given in \a to. + Returns true if the indexes were in 0..\l count - 1 boundary and if the operation + succeeds, and false otherwise. The \l selectedTabIndex is updated if it is + affected by the move (it is equal with \a from or falls between \a from and + \a to indexes). + */ + function moveTab(from, to) { + if (from < 0 || from >= count || to < 0 || to >= count || from === to) return false; + var tabFrom = tabsModel.get(from).tab; + var tabTo = tabsModel.get(to).tab; + + // move tab + tabsModel.move(from, to, 1); + tabsModel.reindex(); + + // fix selected tab + if (selectedTabIndex === from) { + selectedTabIndex = to; + } else if (selectedTabIndex <= to && selectedTabIndex >= from) { + selectedTabIndex -= 1; + } else { + tabs.modelChanged(); + } + + return true; + } + + /*! + Removes the Tab from the given \a index. Returns true if the \a index falls + into 0..\l count - 1 boundary and the operation succeeds, and false on error. + The function removes also the pre-declared tabs. These can be added back using + \l addTab or \l insertTab by specifying the instance of the Tab to be added as + component. The \l selectedTabIndex is updated if is affected by the removal + (it is identical or greater than the tab index to be removed). + */ + function removeTab(index) { + if (index < 0 || index >= count) return false; + var tab = tabsModel.get(index).tab; + var activeIndex = (selectedTabIndex >= index) ? MathUtils.clamp(selectedTabIndex, 0, count - 2) : -1; + + tabsModel.remove(index); + tabsModel.reindex(); + // move active tab if needed + if (activeIndex >= 0) { + selectedTabIndex = activeIndex; + } + + if (tab.__protected.dynamic) { + tab.destroy(); + } else { + // pre-declared tab, mark it as removed, so we don't update it next time + // the tabs stack children is updated + tab.__protected.removedFromTabs = true; + } + + if (activeIndex < 0) { + tabs.modelChanged(); + } + return true; + } + + /*! \internal required by TabsStyle */ - Item { - anchors.fill: parent + ListModel { id: tabsModel - property var tabList: [] - onChildrenChanged: { - updateTabList(); + function listModel(tab) { + return {"title": tab.title, "tab": tab}; } - function updateTabList() { - var list = []; - var index = 0; - for (var i=0; i < children.length; i++) { - if (isTab(tabsModel.children[i])) { - tabsModel.children[i].__protected.index = index++; - list.push(tabsModel.children[i]); + function updateTabList(tabsList) { + for (var i in tabsList) { + var tab = tabsList[i]; + if (internal.isTab(tab)) { + // make sure we have the right parent + tab.parent = tabStack; + + if (!tab.__protected.inserted) { + tab.__protected.index = count; + tab.__protected.inserted = true; + append(listModel(tab)); + } else if (!tab.__protected.removedFromTabs && tabsModel.count > tab.index) { + get(tab.index).title = tab.title; + } } } - tabList = list; tabs.modelChanged(); } - function isTab(item) { - if (item && item.hasOwnProperty("__isPageTreeNode") - && item.__isPageTreeNode && item.hasOwnProperty("title") - && item.hasOwnProperty("page")) { - return true; - } else { - return false; + function reindex(from) { + var start = 0; + if (from !== undefined) { + start = from + 1; + } + + for (var i = start; i < count; i++) { + var tab = get(i).tab; + tab.__protected.index = i; } } + + } + + Item { + anchors.fill: parent + id: tabStack + + onChildrenChanged: tabsModel.updateTabList(children) } /*! \internal */ @@ -240,6 +388,16 @@ QtObject { id: internal property Header header: tabs.__propagated ? tabs.__propagated.header : null + + function isTab(item) { + if (item && item.hasOwnProperty("__isPageTreeNode") + && item.__isPageTreeNode && item.hasOwnProperty("title") + && item.hasOwnProperty("page")) { + return true; + } else { + return false; + } + } } Binding { diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/Themes/Ambiance/TabBarStyle.qml ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/Themes/Ambiance/TabBarStyle.qml --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/Themes/Ambiance/TabBarStyle.qml 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/Themes/Ambiance/TabBarStyle.qml 2013-11-18 17:13:10.000000000 +0000 @@ -41,6 +41,7 @@ The set of tabs this tab bar belongs to */ property Tabs tabs: styledItem ? styledItem.tabsItem : null + property ListModel tabsModel : styledItem ? styledItem.model : null Connections { target: styledItem @@ -90,7 +91,7 @@ Repeater { id: repeater - model: tabs.__tabs + model: tabsModel AbstractButton { id: button @@ -123,7 +124,7 @@ // When we don't need scrolling, we want to avoid showing a button that is fading // while sliding in from the right side when a new button was selected - var numTabs = tabs.__tabs.length; + var numTabs = tabsModel.count; var minimum = buttonView.selectedButtonIndex; var maximum = buttonView.selectedButtonIndex + numTabs - 1; if (MathUtils.clamp(buttonIndex, minimum, maximum) === buttonIndex) return true; @@ -179,7 +180,7 @@ baseline: parent.bottom baselineOffset: -headerTextBottomMargin } - text: modelData.title + text: (tab && tab.hasOwnProperty("title")) ? tab.title : title fontSize: headerFontSize font.weight: headerFontWeight } @@ -254,7 +255,7 @@ // Select the closest of the two buttons that represent the given tab index function selectButton(tabIndex) { - if (tabIndex < 0 || tabIndex >= tabs.__tabs.length) return; + if (tabIndex < 0 || tabIndex >= tabsModel.count) return; if (buttonView.buttonRow1 && buttonView.buttonRow2) { var b1 = buttonView.buttonRow1.children[tabIndex]; var b2 = buttonView.buttonRow2.children[tabIndex]; diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/plugin/inversemouseareatype.cpp ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/plugin/inversemouseareatype.cpp --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/modules/Ubuntu/Components/plugin/inversemouseareatype.cpp 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/modules/Ubuntu/Components/plugin/inversemouseareatype.cpp 2013-11-18 17:13:10.000000000 +0000 @@ -319,6 +319,9 @@ bool InverseMouseAreaType::eventFilter(QObject *object, QEvent *event) { + if (!isEnabled()) + return false; + if (object != this) { bool captured = true; diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/ca.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/ca.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/ca.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/ca.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/de.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/de.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/de.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/de.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/es.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/es.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/es.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/es.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/fi.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/fi.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/fi.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/fi.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/fr.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/fr.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/fr.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/fr.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/gl.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/gl.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/gl.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/gl.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/he.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/he.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/he.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/he.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/ko.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/ko.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/ko.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/ko.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/my.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/my.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/my.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/my.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/nl.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/nl.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/nl.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/nl.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/oc.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/oc.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/oc.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/oc.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:23+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/sv.po ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/sv.po --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/po/sv.po 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/po/sv.po 2013-11-18 17:13:10.000000000 +0000 @@ -14,7 +14,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-02 06:24+0000\n" +"X-Launchpad-Export-Date: 2013-11-12 06:23+0000\n" "X-Generator: Launchpad (build 16820)\n" #: examples/ubuntu-ui-toolkit-gallery/Animations.qml:22 diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/autopilot/ubuntuuitoolkit/base.py ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/autopilot/ubuntuuitoolkit/base.py --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/autopilot/ubuntuuitoolkit/base.py 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/autopilot/ubuntuuitoolkit/base.py 2013-11-18 17:13:10.000000000 +0000 @@ -32,7 +32,7 @@ # QT_SELECT=qt5 doesn't work for autopilot tests. --Mirv - 2013-10-03 arch = subprocess.check_output( ["dpkg-architecture", "-qDEB_HOST_MULTIARCH"]).strip() - return '/usr/lib/' + arch + '/qt5/bin/qmlscene' + return '/usr/lib/{}/qt5/bin/qmlscene'.format(arch.decode()) class UbuntuUIToolkitAppTestCase(testcase.AutopilotTestCase): diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/autopilot/ubuntuuitoolkit/emulators.py ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/autopilot/ubuntuuitoolkit/emulators.py --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/autopilot/ubuntuuitoolkit/emulators.py 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/autopilot/ubuntuuitoolkit/emulators.py 2013-11-18 17:13:10.000000000 +0000 @@ -426,39 +426,58 @@ class Empty(UbuntuUIToolkitEmulatorBase): - """Base class to emulate swipe to delete""" + """Base class to emulate swipe to delete.""" + + def exists(self): + try: + return self.implicitHeight > 0 + except dbus.StateNotFoundError: + return False def _get_confirm_button(self): return self.select_single( 'QQuickItem', objectName='confirmRemovalDialog') def swipe_to_delete(self, direction='right'): - """ Swipe the item in a specific direction """ + """Swipe the item in a specific direction.""" if (self.removable): - x, y, w, h = self.globalRect - tx = x + (w / 8) - ty = y + (h / 2) - - if (direction == 'right'): - self.pointing_device.drag(tx, ty, w, ty) - elif (direction == 'left'): - self.pointing_device.drag(w - (w*0.1), ty, x, ty) + self._drag_pointing_device_to_delete(direction) + if self.confirmRemoval: + self.waitingConfirmationForRemoval.wait_for(True) else: - raise ToolkitEmulatorException( - 'Invalid direction "{0}" used on swipe to delete function' - .format(direction)) - - self.waitingConfirmationForRemoval.wait_for(True) + self._wait_until_deleted() else: raise ToolkitEmulatorException( 'The item "{0}" is not removable'.format(self.objectName)) + def _drag_pointing_device_to_delete(self, direction): + x, y, w, h = self.globalRect + tx = x + (w / 8) + ty = y + (h / 2) + + if (direction == 'right'): + self.pointing_device.drag(tx, ty, w, ty) + elif (direction == 'left'): + self.pointing_device.drag(w - (w*0.1), ty, x, ty) + else: + raise ToolkitEmulatorException( + 'Invalid direction "{0}" used on swipe to delete function' + .format(direction)) + + def _wait_until_deleted(self): + try: + # The item was hidden. + self.implicitHeight.wait_for(0) + except dbus.StateNotFoundError: + # The item was destroyed. + pass + def confirm_removal(self): - """ Comfirm item removal if this was already swiped """ + """Comfirm item removal if this was already swiped.""" if (self.waitingConfirmationForRemoval): deleteButton = self._get_confirm_button() self.pointing_device.click_object(deleteButton) - self.implicitHeight.wait_for(0) + self._wait_until_deleted() else: raise ToolkitEmulatorException( 'The item "{0}" is not waiting for removal confirmation'. diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/autopilot/ubuntuuitoolkit/tests/__init__.py ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/autopilot/ubuntuuitoolkit/tests/__init__.py --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/autopilot/ubuntuuitoolkit/tests/__init__.py 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/autopilot/ubuntuuitoolkit/tests/__init__.py 2013-11-18 17:13:10.000000000 +0000 @@ -41,7 +41,7 @@ os.makedirs(desktop_file_dir) desktop_file = tempfile.NamedTemporaryFile( suffix='.desktop', dir=desktop_file_dir, delete=False) - desktop_file.write(_DESKTOP_FILE_CONTENTS) + desktop_file.write(_DESKTOP_FILE_CONTENTS.encode('utf-8')) desktop_file.close() return desktop_file.name @@ -96,7 +96,7 @@ def _write_test_qml_file(self): qml_file = tempfile.NamedTemporaryFile(suffix='.qml', delete=False) - qml_file.write(self.test_qml) + qml_file.write(self.test_qml.encode('utf-8')) qml_file.close() return qml_file.name diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py 2013-11-18 17:13:10.000000000 +0000 @@ -31,9 +31,9 @@ textfield_standard = self.getObject('textfield_standard') self.pointing_device.click_object(textfield_standard) self.assertThat(textfield_standard.focus, Eventually(Equals(True))) - self.type_string(u'Hello World') + self.type_string('Hello World') self.assertThat(textfield_standard.text, - Eventually(Equals(u'Hello World'))) + Eventually(Equals('Hello World'))) def test_textfield_password(self): item = "Text Field" @@ -46,9 +46,9 @@ self.tap_clearButton('textfield_password') self.assertThat(textfield_password.text, Eventually(Equals(''))) - self.type_string(u'abcdefgh123') + self.type_string('abcdefgh123') self.assertThat(textfield_password.text, - Eventually(Equals(u'abcdefgh123'))) + Eventually(Equals('abcdefgh123'))) def test_textfield_numbers(self): item = "Text Field" diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py 2013-11-18 17:13:10.000000000 +0000 @@ -107,14 +107,14 @@ error = self.assertRaises( emulators.ToolkitEmulatorException, self.main_view.get_tabs) self.assertEqual( - error.message, 'The MainView has no Tabs.') + str(error), 'The MainView has no Tabs.') def test_switch_to_next_tab_without_tabs(self): header = self.main_view.get_header() error = self.assertRaises( emulators.ToolkitEmulatorException, header.switch_to_next_tab) self.assertEqual( - error.message, 'The MainView has no Tabs.') + str(error), 'The MainView has no Tabs.') class PageTestCase(tests.QMLStringAppTestCase): @@ -223,14 +223,14 @@ emulators.ToolkitEmulatorException, self.toolbar.click_button, 'unexisting') self.assertEqual( - error.message, 'Button with objectName "unexisting" not found.') + str(error), 'Button with objectName "unexisting" not found.') def test_click_button_on_closed_toolbar(self): error = self.assertRaises( emulators.ToolkitEmulatorException, self.toolbar.click_button, 'buttonName') self.assertEqual( - error.message, + str(error), 'Toolbar must be opened before calling click_button().') @@ -333,7 +333,7 @@ emulators.ToolkitEmulatorException, self.main_view.switch_to_tab_by_index, last_tab_index + 1) - self.assertEqual(error.message, 'Tab index out of range.') + self.assertEqual(str(error), 'Tab index out of range.') def test_switch_to_previous_tab_from_first(self): current_tab = self.main_view.switch_to_previous_tab() @@ -357,7 +357,7 @@ emulators.ToolkitEmulatorException, self.main_view.switch_to_tab, 'unexisting') self.assertEqual( - error.message, 'Tab with objectName "unexisting" not found.') + str(error), 'Tab with objectName "unexisting" not found.') class ActionSelectionPopoverTestCase(tests.QMLStringAppTestCase): @@ -424,7 +424,7 @@ emulators.ToolkitEmulatorException, popover.click_button_by_text, 'unexisting') self.assertEqual( - error.message, 'Button with text "unexisting" not found.') + str(error), 'Button with text "unexisting" not found.') def test_click_button_with_closed_popover(self): popover = self.main_view.get_action_selection_popover( @@ -433,7 +433,7 @@ emulators.ToolkitEmulatorException, popover.click_button_by_text, 'Action one') self.assertEqual( - error.message, 'The popover is not open.') + str(error), 'The popover is not open.') TEST_QML_WITH_CHECKBOX = (""" @@ -555,21 +555,59 @@ MainView { width: units.gu(48) - height: units.gu(300) + height: units.gu(60) + + Page { - Column { - width: parent.width + ListModel { + id: testModel - Standard { - objectName: "listitem_standard" - confirmRemoval: true - removable: true - width: parent.width - text: 'Slide to remove' - } - Empty { - objectName: "listitem_empty" - width: parent.width + ListElement { + name: "listitem_destroyed_on_remove_with_confirm" + label: "Item destroyed on remove with confirmation" + confirm: true + } + ListElement { + name: "listitem_destroyed_on_remove_without_confirm" + label: "Item destroyed on remove without confirmation" + confirm: false + } + } + + Column { + anchors { fill: parent } + + Standard { + objectName: "listitem_standard" + confirmRemoval: true + removable: true + text: 'Slide to remove' + } + + Empty { + objectName: "listitem_empty" + } + + Standard { + objectName: "listitem_without_confirm" + confirmRemoval: false + removable: true + text: "Item without delete confirmation" + } + + ListView { + anchors { left: parent.left; right: parent.right } + height: childrenRect.height + model: testModel + + delegate: Standard { + removable: true + confirmRemoval: confirm + onItemRemoved: testModel.remove(index) + text: label + objectName: name + } + } } } } @@ -579,6 +617,7 @@ super(SwipeToDeleteTestCase, self).setUp() self._item = self.main_view.select_single( emulators.Standard, objectName='listitem_standard') + self.assertTrue(self._item.exists()) def test_supported_class(self): self.assertTrue(issubclass( @@ -619,12 +658,12 @@ def test_delete_item_moving_right(self): self._item.swipe_to_delete('right') self._item.confirm_removal() - self.assertEqual(self._item.implicitHeight, 0) + self.assertFalse(self._item.exists()) def test_delete_item_moving_left(self): self._item.swipe_to_delete('left') self._item.confirm_removal() - self.assertEqual(self._item.implicitHeight, 0) + self.assertFalse(self._item.exists()) def test_delete_non_removable_item(self): self._item = self.main_view.select_single( @@ -636,6 +675,27 @@ self.assertRaises( emulators.ToolkitEmulatorException, self._item.confirm_removal) + def test_delete_item_without_confirm(self): + item = self.main_view.select_single( + emulators.Standard, objectName='listitem_without_confirm') + item.swipe_to_delete() + self.assertFalse(item.exists()) + + def test_delete_item_with_confirmation_that_will_be_destroyed(self): + item = self.main_view.select_single( + emulators.Standard, + objectName='listitem_destroyed_on_remove_with_confirm') + item.swipe_to_delete() + item.confirm_removal() + self.assertFalse(item.exists()) + + def test_delete_item_without_confirmation_that_will_be_destroyed(self): + item = self.main_view.select_single( + emulators.Standard, + objectName='listitem_destroyed_on_remove_without_confirm') + item.swipe_to_delete() + self.assertFalse(item.exists()) + class PageStackTestCase(tests.QMLStringAppTestCase): diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/resources/navigation/Tabs.qml ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/resources/navigation/Tabs.qml --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/resources/navigation/Tabs.qml 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/resources/navigation/Tabs.qml 2013-11-18 17:13:10.000000000 +0000 @@ -21,6 +21,28 @@ MainView { width: 800 height: 600 + + Component { + id: dynamicTab + Tab { + title: "Original Title #" + index + page: Page { + Row { + anchors.centerIn: parent + spacing: 5 + Button { + text: "Delete" + onClicked: tabs.removeTab(index) + } + Button { + text: "Move to 0" + onClicked: tabs.moveTab(index, 0) + } + } + } + } + } + Tabs { id: tabs selectedTabIndex: 0 @@ -29,7 +51,8 @@ } Tab { - title: i18n.tr("Simple page") + id: simpleTab + title: i18n.tr("Simple page #" + index) page: Page { title: "This title is not visible" Row { @@ -54,13 +77,37 @@ iconSource: "call_icon.png" onTriggered: print("action triggered") } + ToolbarButton { + text: "ADD" + iconSource: "call_icon.png" + onTriggered: tabs.addTab("", dynamicTab) + } + ToolbarButton { + text: "INSERT" + iconSource: "call_icon.png" + onTriggered: tabs.insertTab(1, "INSERTED", dynamicTab) + } + ToolbarButton { + text: "move me next" + iconSource: "call_icon.png" + onTriggered: { + var i = simpleTab.index; + tabs.moveTab(i, i + 1); + } + } + ToolbarButton { + text: "delete 0" + iconSource: "call_icon.png" + onTriggered: tabs.removeTab(0) + } } } } Repeater { model: 3 Tab { - title: "Extra " + index + id: tab + title: "Extra #" + tab.index page: Page { Column { anchors.centerIn: parent @@ -86,7 +133,7 @@ } Tab { id: externalTab - title: i18n.tr("External") + title: i18n.tr("External #" + index) page: Loader { parent: externalTab anchors.fill: parent @@ -94,7 +141,7 @@ } } Tab { - title: i18n.tr("List view") + title: i18n.tr("List view #" + index) page: Page { ListView { clip: true diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/unit_x11/tst_components/ExternalTab.qml ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/unit_x11/tst_components/ExternalTab.qml --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/unit_x11/tst_components/ExternalTab.qml 1970-01-01 00:00:00.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/unit_x11/tst_components/ExternalTab.qml 2013-11-18 17:13:10.000000000 +0000 @@ -0,0 +1,21 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.0 +import Ubuntu.Components 0.1 + +Tab { +} diff -Nru ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/unit_x11/tst_components/tst_tabs.qml ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/unit_x11/tst_components/tst_tabs.qml --- ubuntu-ui-toolkit-0.1.46+14.04.20131108.4/tests/unit_x11/tst_components/tst_tabs.qml 2013-11-08 23:10:59.000000000 +0000 +++ ubuntu-ui-toolkit-0.1.46+14.04.20131118/tests/unit_x11/tst_components/tst_tabs.qml 2013-11-18 17:13:10.000000000 +0000 @@ -26,6 +26,13 @@ id: emptyTabs } + Component { + id: dynamicTab + Tab{ + title: "OriginalTitle" + } + } + MainView { id: mainView anchors.fill: parent @@ -184,5 +191,153 @@ mouseClick(button, units.gu(1), units.gu(1), Qt.LeftButton); compare(tabs.tabBar.selectionMode, false, "Tab bar deactivated by interacting with the page contents"); } + + function test_z_addTab() { + var newTab = tabs.addTab("Dynamic Tab", dynamicTab); + compare((newTab !== null), true, "tab added"); + compare(newTab.active, false, "the inserted tab is inactive"); + compare(newTab.index, tabs.count - 1, "the tab is the last one"); + } + + function test_z_addExternalTab() { + var newTab = tabs.addTab("External Tab", Qt.resolvedUrl("ExternalTab.qml")); + compare((newTab !== null), true, "tab added"); + compare(newTab.active, false, "the inserted tab is inactive"); + compare(newTab.index, tabs.count - 1, "the tab is the last one"); + } + + function test_z_addTabWithDefaultTitle() { + var newTab = tabs.addTab("", dynamicTab); + compare((newTab !== null), true, "tab added"); + compare(newTab.title, "OriginalTitle", "tab created with original title"); + } + + function test_z_insertTab() { + var tabIndex = Math.ceil(tabs.count / 2); + var newTab = tabs.insertTab(tabIndex, "Inserted tab", dynamicTab); + compare((newTab !== null), true, "tab inserted"); + compare(newTab.index, tabIndex, "this is the first tab"); + compare(tabs.selectedTab !== newTab, true, "the new tab is not the active one"); + } + + function test_z_insertExternalTab() { + var tabIndex = Math.ceil(tabs.count / 2); + var newTab = tabs.insertTab(tabIndex, "Inserted External tab", Qt.resolvedUrl("ExternalTab.qml")); + compare((newTab !== null), true, "tab inserted"); + compare(newTab.index, tabIndex, "this is the first tab"); + compare(tabs.selectedTab !== newTab, true, "the new tab is not the active one"); + } + + function test_z_insertTabAtSelectedIndex() { + tabs.selectedTabIndex = 1; + var tabIndex = tabs.selectedTabIndex - 1; + var newTab = tabs.insertTab(tabIndex, "InsertedAtSelected tab", dynamicTab); + compare((newTab !== null), true, "tab inserted"); + compare(newTab.index, tabIndex, "inserted at selected tab"); + compare(tabs.selectedTabIndex != (tabIndex + 1), true, "it is not the selected tab"); + } + + function test_z_insertTabFront() { + var newTab = tabs.insertTab(-1, "PreTab", dynamicTab); + compare(newTab !== null, true, "pre-tab inserted"); + compare(newTab.index, 0, "this is the new first tab"); + compare(tabs.selectedTab !== newTab, true, "the new tab is not the active one"); + } + + function test_z_insertTabEnd() { + var newTab = tabs.insertTab(tabs.count, "PostTab", dynamicTab); + compare(newTab !== null, true, "post-tab inserted"); + compare(newTab.index, tabs.count - 1, "thsi is the new last tab"); + compare(tabs.selectedTab !== newTab, true, "the new tab is not the active one"); + } + + function test_z_insertTabAndActivate() { + var newTab = tabs.addTab("Inserted tab", dynamicTab); + compare((newTab !== null), true, "tab inserted"); + compare(newTab.index, tabs.count - 1, "the tab is the last one"); + tabs.selectedTabIndex = newTab.index; + compare(tabs.selectedTab, newTab, "the inserted tab is selected"); + compare(newTab.active, true, "the new tab is active"); + } + + function test_z_moveTab() { + var selectedIndex = tabs.count - 1; + tabs.selectedTabIndex = selectedIndex; + compare(tabs.moveTab(0, selectedIndex), true, "first tab moved to last"); + compare(tabs.selectedTabIndex, selectedIndex - 1, "the selected index moved backwards"); + tabs.selectedTabIndex = selectedIndex = 0; + compare(tabs.moveTab(selectedIndex, selectedIndex + 1), true, "selected tab moved as next"); + compare(tabs.selectedTabIndex, selectedIndex + 1, "the selected index moved forewards"); + } + + function test_z_moveSelectedTab() { + tabs.selectedTabIndex = 0; + tabs.moveTab(0, 1); + compare(tabs.selectedTabIndex, 1, "selected tab moved"); + } + + function test_z_moveTabFail() { + compare(tabs.moveTab(-1, tabs.count - 1), false, "from-parameter out of range"); + compare(tabs.moveTab(0, tabs.count), false, "to-parameter out of range"); + } + + function test_z_removeTab() { + compare(tabs.removeTab(tabs.count - 1), true, "last tab removed"); + tabs.selectedTabIndex = 0; + compare(tabs.removeTab(0), true, "active tab removed"); + compare(tabs.selectedTabIndex, 0, "the next tab is selected") + } + + function test_z_removeTabAfterActiveTab() { + var activeTab = tabs.count - 2; + tabs.selectedTabIndex = activeTab; + compare(tabs.removeTab(tabs.count - 1), true, "last tab removed"); + compare(tabs.selectedTabIndex, activeTab, "the selected tab wasn't moved"); + } + + function test_z_removeTabBeforeActiveTab() { + var activeTab = tabs.count - 1; + tabs.selectedTabIndex = activeTab; + compare(tabs.removeTab(0), true, "first tab removed"); + compare(tabs.selectedTabIndex, activeTab - 1, "the selected tab index decreased"); + } + + function test_z_removeActiveTab() { + tabs.selectedTabIndex = 1; + compare(tabs.removeTab(1), true, "selected tab removed"); + compare(tabs.selectedTabIndex, 1, "selected tab is next"); + + tabs.selectedTabIndex = tabs.count - 1; + compare(tabs.removeTab(tabs.count - 1), true, "last tab removed"); + compare(tabs.selectedTabIndex, tabs.count - 1, "selected tab moved to last item"); + } + + function test_zz_addTabAfterCleaningUpTabs() { + while (tabs.count > 1) { + tabs.removeTab(0); + } + compare(tabs.selectedTabIndex, 0, "the only tab is the selected one"); + // add a new tab anc check the count (default added tas should not be added anymore + tabs.addTab("Second tab", dynamicTab); + compare(tabs.count, 2, "we have two tabs only"); + } + + function test_zz_addPredeclaredTab() { + while (tabs.count > 1) { + tabs.removeTab(0); + } + compare(tabs.selectedTabIndex, 0, "the only tab is the selected one"); + + // add a predeclared tab back with original title + compare(tabs.addTab("", tab1), tab1, "tab1 was added back"); + compare(tab1.title, "tab 1", "with the original title"); + + // add a predeclared tab back with new title + compare(tabs.addTab("Original tab", tab2), tab2, "tab2 was added back"); + compare(tab2.title, "Original tab", "with modified title"); + + // add a predeclared tab which was added already + compare(tabs.addTab("", tab1), null, "tab1 is already in tabs"); + } } }