diff --git a/ico/16x16/go-down.png b/ico/16x16/go-down.png new file mode 100644 index 000000000..5891219e4 Binary files /dev/null and b/ico/16x16/go-down.png differ diff --git a/ico/16x16/go-up.png b/ico/16x16/go-up.png new file mode 100644 index 000000000..b3d9cef97 Binary files /dev/null and b/ico/16x16/go-up.png differ diff --git a/ico/22x22/go-down.png b/ico/22x22/go-down.png new file mode 100644 index 000000000..63331a575 Binary files /dev/null and b/ico/22x22/go-down.png differ diff --git a/ico/22x22/go-up.png b/ico/22x22/go-up.png new file mode 100644 index 000000000..4459024ea Binary files /dev/null and b/ico/22x22/go-up.png differ diff --git a/qelectrotech.qrc b/qelectrotech.qrc index 7824abad1..d963be118 100644 --- a/qelectrotech.qrc +++ b/qelectrotech.qrc @@ -44,7 +44,9 @@ ico/16x16/endline-triangle.png ico/16x16/folder-new.png ico/16x16/folder.png + ico/16x16/go-down.png ico/16x16/go-home.png + ico/16x16/go-up.png ico/16x16/ground.png ico/16x16/item_cancel.png ico/16x16/item_copy.png @@ -118,7 +120,9 @@ ico/22x22/folder-delete.png ico/22x22/folder-edit.png ico/22x22/folder-new.png + ico/22x22/go-down.png ico/22x22/go-home.png + ico/22x22/go-up.png ico/22x22/hotspot.png ico/22x22/landscape.png ico/22x22/line.png diff --git a/sources/elementspanel.cpp b/sources/elementspanel.cpp index 79b28126e..32d7f4383 100644 --- a/sources/elementspanel.cpp +++ b/sources/elementspanel.cpp @@ -913,8 +913,12 @@ void ElementsPanel::diagramOrderChanged(QETProject *project, int from, int to) { if (!moved_qtwi_diagram) return; // enleve le QTWI et le reinsere au bon endroit + bool was_selected = moved_qtwi_diagram -> isSelected(); qtwi_project -> removeChild(moved_qtwi_diagram); qtwi_project -> insertChild(to, moved_qtwi_diagram); + if (was_selected) { + setCurrentItem(moved_qtwi_diagram); + } } /** diff --git a/sources/elementspanelwidget.cpp b/sources/elementspanelwidget.cpp index 02bdbcbcf..035661b4e 100644 --- a/sources/elementspanelwidget.cpp +++ b/sources/elementspanelwidget.cpp @@ -48,24 +48,26 @@ ElementsPanelWidget::ElementsPanelWidget(QWidget *parent) : QWidget(parent) { elements_panel = new ElementsPanel(this); // initialise les actions - reload = new QAction(QET::Icons::ViewRefresh, tr("Recharger les collections"), this); - new_category = new QAction(QET::Icons::FolderNew, tr("Nouvelle cat\351gorie"), this); - edit_category = new QAction(QET::Icons::FolderEdit, tr("\311diter la cat\351gorie"), this); - delete_category = new QAction(QET::Icons::FolderDelete, tr("Supprimer la cat\351gorie"), this); - delete_collection = new QAction(QET::Icons::FolderDelete, tr("Vider la collection"), this); - new_element = new QAction(QET::Icons::ElementNew, tr("Nouvel \351l\351ment"), this); - import_element = new QAction(QET::Icons::DocumentImport, tr("Importer un \351l\351ment"), this); - edit_element = new QAction(QET::Icons::ElementEdit, tr("\311diter l'\351l\351ment"), this); - delete_element = new QAction(QET::Icons::ElementDelete, tr("Supprimer l'\351l\351ment"), this); - prj_close = new QAction(QET::Icons::DocumentClose, tr("Fermer ce projet"), this); - prj_edit_prop = new QAction(QET::Icons::DialogInformation, tr("Propri\351t\351s du projet"), this); - prj_prop_diagram = new QAction(QET::Icons::DialogInformation, tr("Propri\351t\351s du sch\351ma"), this); - prj_add_diagram = new QAction(QET::Icons::DiagramAdd, tr("Ajouter un sch\351ma"), this); - prj_del_diagram = new QAction(QET::Icons::DiagramDelete, tr("Supprimer ce sch\351ma"), this); - move_elements_ = new QAction(QET::Icons::MoveFile, tr("D\351placer dans cette cat\351gorie"), this); - copy_elements_ = new QAction(QET::Icons::CopyFile, tr("Copier dans cette cat\351gorie"), this); - cancel_elements_ = new QAction(QET::Icons::Cancel, tr("Annuler"), this); - erase_textfield = new QAction(QET::Icons::EditClearLocationBar, tr("Effacer le filtre"), this); + reload = new QAction(QET::Icons::ViewRefresh, tr("Recharger les collections"), this); + new_category = new QAction(QET::Icons::FolderNew, tr("Nouvelle cat\351gorie"), this); + edit_category = new QAction(QET::Icons::FolderEdit, tr("\311diter la cat\351gorie"), this); + delete_category = new QAction(QET::Icons::FolderDelete, tr("Supprimer la cat\351gorie"), this); + delete_collection = new QAction(QET::Icons::FolderDelete, tr("Vider la collection"), this); + new_element = new QAction(QET::Icons::ElementNew, tr("Nouvel \351l\351ment"), this); + import_element = new QAction(QET::Icons::DocumentImport, tr("Importer un \351l\351ment"), this); + edit_element = new QAction(QET::Icons::ElementEdit, tr("\311diter l'\351l\351ment"), this); + delete_element = new QAction(QET::Icons::ElementDelete, tr("Supprimer l'\351l\351ment"), this); + prj_close = new QAction(QET::Icons::DocumentClose, tr("Fermer ce projet"), this); + prj_edit_prop = new QAction(QET::Icons::DialogInformation, tr("Propri\351t\351s du projet"), this); + prj_prop_diagram = new QAction(QET::Icons::DialogInformation, tr("Propri\351t\351s du sch\351ma"), this); + prj_add_diagram = new QAction(QET::Icons::DiagramAdd, tr("Ajouter un sch\351ma"), this); + prj_del_diagram = new QAction(QET::Icons::DiagramDelete, tr("Supprimer ce sch\351ma"), this); + prj_move_diagram_up = new QAction(QET::Icons::GoUp, tr("Remonter ce sch\351ma"), this); + prj_move_diagram_down = new QAction(QET::Icons::GoDown, tr("Abaisser ce sch\351ma"), this); + move_elements_ = new QAction(QET::Icons::MoveFile, tr("D\351placer dans cette cat\351gorie"), this); + copy_elements_ = new QAction(QET::Icons::CopyFile, tr("Copier dans cette cat\351gorie"), this); + cancel_elements_ = new QAction(QET::Icons::Cancel, tr("Annuler"), this); + erase_textfield = new QAction(QET::Icons::EditClearLocationBar, tr("Effacer le filtre"), this); // initialise le champ de texte pour filtrer avec une disposition horizontale QLabel *filter_label = new QLabel(tr("Filtrer : "), this); @@ -84,29 +86,31 @@ ElementsPanelWidget::ElementsPanelWidget(QWidget *parent) : QWidget(parent) { context_menu = new QMenu(this); - connect(reload, SIGNAL(triggered()), this, SLOT(reloadAndFilter())); - connect(new_category, SIGNAL(triggered()), this, SLOT(newCategory())); - connect(edit_category, SIGNAL(triggered()), this, SLOT(editCategory())); - connect(delete_category, SIGNAL(triggered()), this, SLOT(deleteCategory())); - connect(delete_collection, SIGNAL(triggered()), this, SLOT(deleteCategory())); - connect(new_element, SIGNAL(triggered()), this, SLOT(newElement())); - connect(import_element, SIGNAL(triggered()), this, SLOT(importElement())); - connect(edit_element, SIGNAL(triggered()), this, SLOT(editElement())); - connect(delete_element, SIGNAL(triggered()), this, SLOT(deleteElement())); - connect(prj_close, SIGNAL(triggered()), this, SLOT(closeProject())); - connect(prj_edit_prop, SIGNAL(triggered()), this, SLOT(editProjectProperties())); - connect(prj_prop_diagram, SIGNAL(triggered()), this, SLOT(editDiagramProperties())); - connect(prj_add_diagram, SIGNAL(triggered()), this, SLOT(newDiagram())); - connect(prj_del_diagram, SIGNAL(triggered()), this, SLOT(deleteDiagram())); - connect(move_elements_, SIGNAL(triggered()), this, SLOT(moveElements())); - connect(copy_elements_, SIGNAL(triggered()), this, SLOT(copyElements())); + connect(reload, SIGNAL(triggered()), this, SLOT(reloadAndFilter())); + connect(new_category, SIGNAL(triggered()), this, SLOT(newCategory())); + connect(edit_category, SIGNAL(triggered()), this, SLOT(editCategory())); + connect(delete_category, SIGNAL(triggered()), this, SLOT(deleteCategory())); + connect(delete_collection, SIGNAL(triggered()), this, SLOT(deleteCategory())); + connect(new_element, SIGNAL(triggered()), this, SLOT(newElement())); + connect(import_element, SIGNAL(triggered()), this, SLOT(importElement())); + connect(edit_element, SIGNAL(triggered()), this, SLOT(editElement())); + connect(delete_element, SIGNAL(triggered()), this, SLOT(deleteElement())); + connect(prj_close, SIGNAL(triggered()), this, SLOT(closeProject())); + connect(prj_edit_prop, SIGNAL(triggered()), this, SLOT(editProjectProperties())); + connect(prj_prop_diagram, SIGNAL(triggered()), this, SLOT(editDiagramProperties())); + connect(prj_add_diagram, SIGNAL(triggered()), this, SLOT(newDiagram())); + connect(prj_del_diagram, SIGNAL(triggered()), this, SLOT(deleteDiagram())); + connect(prj_move_diagram_up, SIGNAL(triggered()), this, SLOT(moveDiagramUp())); + connect(prj_move_diagram_down, SIGNAL(triggered()), this, SLOT(moveDiagramDown())); + connect(move_elements_, SIGNAL(triggered()), this, SLOT(moveElements())); + connect(copy_elements_, SIGNAL(triggered()), this, SLOT(copyElements())); - connect(erase_textfield, SIGNAL(triggered()), this, SLOT(clearFilterTextField())); - connect(filter_textfield, SIGNAL(textEdited(const QString &)), elements_panel, SLOT(filter(const QString &))); + connect(erase_textfield, SIGNAL(triggered()), this, SLOT(clearFilterTextField())); + connect(filter_textfield, SIGNAL(textEdited(const QString &)), elements_panel, SLOT(filter(const QString &))); - connect(elements_panel, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(updateButtons())); - connect(elements_panel, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(handleContextMenu(const QPoint &))); - connect(elements_panel, SIGNAL(requestForCollectionItem(ElementsCollectionItem *)), this, SLOT(handleCollectionRequest(ElementsCollectionItem *))); + connect(elements_panel, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(updateButtons())); + connect(elements_panel, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(handleContextMenu(const QPoint &))); + connect(elements_panel, SIGNAL(requestForCollectionItem(ElementsCollectionItem *)), this, SLOT(handleCollectionRequest(ElementsCollectionItem *))); connect( elements_panel, SIGNAL(requestForMoveElements(ElementsCollectionItem *, ElementsCollectionItem *, QPoint)), @@ -212,6 +216,24 @@ void ElementsPanelWidget::deleteDiagram() { } } +/** + Emet le signal requestForDiagramMoveUp avec le schema selectionne +*/ +void ElementsPanelWidget::moveDiagramUp() { + if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { + emit(requestForDiagramMoveUp(selected_diagram)); + } +} + +/** + Emet le signal requestForDiagramMoveDown avec le schema selectionne +*/ +void ElementsPanelWidget::moveDiagramDown() { + if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { + emit(requestForDiagramMoveDown(selected_diagram)); + } +} + /** Appelle l'assistant de creation de nouvel element */ @@ -281,10 +303,17 @@ void ElementsPanelWidget::updateButtons() { bool is_writable = !(elements_panel -> selectedProject() -> isReadOnly()); prj_add_diagram -> setEnabled(is_writable); } else if (elements_panel -> selectedItemIsADiagram()) { - bool is_writable = !(elements_panel -> selectedDiagram() -> project() -> isReadOnly()); - prj_del_diagram -> setEnabled(is_writable); + Diagram *selected_diagram = elements_panel -> selectedDiagram(); + QETProject *selected_diagram_project = selected_diagram -> project(); + + bool is_writable = !(selected_diagram_project -> isReadOnly()); + int project_diagrams_count = selected_diagram_project -> diagrams().count(); + int diagram_position = selected_diagram_project -> diagrams().indexOf(selected_diagram); + + prj_del_diagram -> setEnabled(is_writable); + prj_move_diagram_up -> setEnabled(is_writable && diagram_position > 0); + prj_move_diagram_down -> setEnabled(is_writable && diagram_position < project_diagrams_count - 1); } - } /** @@ -321,6 +350,7 @@ void ElementsPanelWidget::handleContextMenu(const QPoint &pos) { QTreeWidgetItem *item = elements_panel -> itemAt(pos); if (!item) return; + updateButtons(); context_menu -> clear(); if (elements_panel -> itemHasLocation(item)) { @@ -351,6 +381,8 @@ void ElementsPanelWidget::handleContextMenu(const QPoint &pos) { } else if (elements_panel -> itemIsADiagram(item)) { context_menu -> addAction(prj_prop_diagram); context_menu -> addAction(prj_del_diagram); + context_menu -> addAction(prj_move_diagram_up); + context_menu -> addAction(prj_move_diagram_down); } } diff --git a/sources/elementspanelwidget.h b/sources/elementspanelwidget.h index 2dd9ba192..c15cdab5a 100644 --- a/sources/elementspanelwidget.h +++ b/sources/elementspanelwidget.h @@ -42,7 +42,7 @@ class ElementsPanelWidget : public QWidget { QAction *new_category, *edit_category, *delete_category; QAction *delete_collection; QAction *new_element, *import_element, *edit_element, *delete_element; - QAction *prj_close, *prj_edit_prop, *prj_prop_diagram, *prj_add_diagram, *prj_del_diagram; + QAction *prj_close, *prj_edit_prop, *prj_prop_diagram, *prj_add_diagram, *prj_del_diagram, *prj_move_diagram_up, *prj_move_diagram_down; QAction *copy_elements_, *move_elements_, *cancel_elements_; QMenu *context_menu; QAction *erase_textfield; @@ -59,6 +59,8 @@ class ElementsPanelWidget : public QWidget { void requestForProjectPropertiesEdition(QETProject *); void requestForDiagramPropertiesEdition(Diagram *); void requestForDiagramDeletion(Diagram *); + void requestForDiagramMoveUp(Diagram *); + void requestForDiagramMoveDown(Diagram *); public slots: void clearFilterTextField(); @@ -68,6 +70,8 @@ class ElementsPanelWidget : public QWidget { void editDiagramProperties(); void newDiagram(); void deleteDiagram(); + void moveDiagramUp(); + void moveDiagramDown(); void newCategory(); void newElement(); void importElement(); diff --git a/sources/projectview.cpp b/sources/projectview.cpp index 259599e08..fd8d89c68 100644 --- a/sources/projectview.cpp +++ b/sources/projectview.cpp @@ -490,6 +490,48 @@ void ProjectView::editDiagramProperties(Diagram *diagram) { editDiagramProperties(findDiagram(diagram)); } +/** + Deplace le schema diagram_view vers le haut / la gauche +*/ +void ProjectView::moveDiagramUp(DiagramView *diagram_view) { + if (!diagram_view) return; + + int diagram_view_position = diagram_ids_.key(diagram_view); + if (!diagram_view_position) { + // le schema est le premier du projet + return; + } + tabs_ -> tabBar() -> moveTab(diagram_view_position, diagram_view_position - 1); +} + +/** + Deplace le schema diagram vers le haut / la gauche +*/ +void ProjectView::moveDiagramUp(Diagram *diagram) { + moveDiagramUp(findDiagram(diagram)); +} + +/** + Deplace le schema diagram_view vers le bas / la droite +*/ +void ProjectView::moveDiagramDown(DiagramView *diagram_view) { + if (!diagram_view) return; + + int diagram_view_position = diagram_ids_.key(diagram_view); + if (diagram_view_position + 1 == diagram_ids_.count()) { + // le schema est le dernier du projet + return; + } + tabs_ -> tabBar() -> moveTab(diagram_view_position, diagram_view_position + 1); +} + +/** + Deplace le schema diagram vers le bas / la droite +*/ +void ProjectView::moveDiagramDown(Diagram *diagram) { + moveDiagramDown(findDiagram(diagram)); +} + /** Ce slot demarre un dialogue permettant a l'utilisateur de parametrer et de lancer l'impression de toute ou partie du projet. diff --git a/sources/projectview.h b/sources/projectview.h index cc712b20a..b36d70ef5 100644 --- a/sources/projectview.h +++ b/sources/projectview.h @@ -54,6 +54,10 @@ class ProjectView : public QWidget { void editCurrentDiagramProperties(); void editDiagramProperties(DiagramView *); void editDiagramProperties(Diagram *); + void moveDiagramUp(DiagramView *); + void moveDiagramUp(Diagram *); + void moveDiagramDown(DiagramView *); + void moveDiagramDown(Diagram *); void printProject(); void exportProject(); bool save(); diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 34e1bcdfd..9f90a81a7 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -67,11 +67,13 @@ QETDiagramEditor::QETDiagramEditor(const QStringList &files, QWidget *parent) : connect(&(pa -> elementsPanel()), SIGNAL(requestForDiagram(Diagram *)), this, SLOT(activateDiagram(Diagram *))); connect(&(pa -> elementsPanel()), SIGNAL(requestForProject(QETProject *)), this, SLOT(activateProject(QETProject *))); - connect(pa, SIGNAL(requestForProjectClosing(QETProject *)), this, SLOT(closeProject(QETProject *))); + connect(pa, SIGNAL(requestForProjectClosing(QETProject *)), this, SLOT(closeProject(QETProject *))); connect(pa, SIGNAL(requestForProjectPropertiesEdition(QETProject *)), this, SLOT(editProjectProperties(QETProject *))); connect(pa, SIGNAL(requestForDiagramPropertiesEdition(Diagram *)), this, SLOT(editDiagramProperties(Diagram *))); - connect(pa, SIGNAL(requestForNewDiagram(QETProject *)), this, SLOT(addDiagramToProject(QETProject *))); - connect(pa, SIGNAL(requestForDiagramDeletion(Diagram *)), this, SLOT(removeDiagram(Diagram *))); + connect(pa, SIGNAL(requestForNewDiagram(QETProject *)), this, SLOT(addDiagramToProject(QETProject *))); + connect(pa, SIGNAL(requestForDiagramDeletion(Diagram *)), this, SLOT(removeDiagram(Diagram *))); + connect(pa, SIGNAL(requestForDiagramMoveUp(Diagram *)), this, SLOT(moveDiagramUp(Diagram *))); + connect(pa, SIGNAL(requestForDiagramMoveDown(Diagram *)), this, SLOT(moveDiagramDown(Diagram *))); qdw_undo = new QDockWidget(tr("Annulations", "dock title")); qdw_undo -> setObjectName("diagram_undo"); @@ -1606,6 +1608,44 @@ void QETDiagramEditor::removeDiagram(Diagram *diagram) { } } +/** + Change l'ordre des schemas d'un projet, en decalant le schema vers le haut / + la gauche + @param diagram Schema a decaler vers le haut / la gauche +*/ +void QETDiagramEditor::moveDiagramUp(Diagram *diagram) { + if (!diagram) return; + + // recupere le projet contenant le schema + if (QETProject *diagram_project = diagram -> project()) { + if (diagram_project -> isReadOnly()) return; + + // recupere la vue sur ce projet + if (ProjectView *project_view = findProject(diagram_project)) { + project_view -> moveDiagramUp(diagram); + } + } +} + +/** + Change l'ordre des schemas d'un projet, en decalant le schema vers le bas / + la droite + @param diagram Schema a decaler vers le bas / la droite +*/ +void QETDiagramEditor::moveDiagramDown(Diagram *diagram) { + if (!diagram) return; + + // recupere le projet contenant le schema + if (QETProject *diagram_project = diagram -> project()) { + if (diagram_project -> isReadOnly()) return; + + // recupere la vue sur ce projet + if (ProjectView *project_view = findProject(diagram_project)) { + project_view -> moveDiagramDown(diagram); + } + } +} + /** Nettoie le projet courant */ diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h index e003022a9..271f82902 100644 --- a/sources/qetdiagrameditor.h +++ b/sources/qetdiagrameditor.h @@ -141,6 +141,8 @@ class QETDiagramEditor : public QMainWindow { void addDiagramToProject(QETProject *); void removeDiagram(Diagram *); void removeDiagramFromProject(); + void moveDiagramUp(Diagram *); + void moveDiagramDown(Diagram *); void cleanCurrentProject(); void diagramWasAdded(DiagramView *); void diagramIsAboutToBeRemoved(DiagramView *); diff --git a/sources/qeticons.cpp b/sources/qeticons.cpp index 568a1fd0c..50a382bab 100644 --- a/sources/qeticons.cpp +++ b/sources/qeticons.cpp @@ -80,6 +80,8 @@ namespace QET { QIcon Forbidden; QIcon FullScreenEnter; QIcon FullScreenExit; + QIcon GoDown; + QIcon GoUp; QIcon Ground; QIcon Hide; QIcon Home; @@ -240,6 +242,10 @@ void QET::Icons::initIcons() { FullScreenEnter .addFile(":/ico/22x22/view-fullscreen.png"); FullScreenExit .addFile(":/ico/16x16/view-restore.png"); FullScreenExit .addFile(":/ico/22x22/view-restore.png"); + GoDown .addFile(":/ico/16x16/go-down.png"); + GoDown .addFile(":/ico/22x22/go-down.png"); + GoUp .addFile(":/ico/16x16/go-up.png"); + GoUp .addFile(":/ico/22x22/go-up.png"); Ground .addFile(":/ico/16x16/ground.png"); Hide .addFile(":/ico/16x16/masquer.png"); Home .addFile(":/ico/16x16/go-home.png"); diff --git a/sources/qeticons.h b/sources/qeticons.h index 9768d9e87..48d60ebb5 100644 --- a/sources/qeticons.h +++ b/sources/qeticons.h @@ -88,6 +88,8 @@ namespace QET { extern QIcon Forbidden; extern QIcon FullScreenEnter; extern QIcon FullScreenExit; + extern QIcon GoDown; + extern QIcon GoUp; extern QIcon Ground; extern QIcon Hide; extern QIcon Home; diff --git a/sources/qettabbar.h b/sources/qettabbar.h index 246c124a8..069942d71 100644 --- a/sources/qettabbar.h +++ b/sources/qettabbar.h @@ -45,6 +45,7 @@ class QETTabBar : public QTabBar { bool isMovable() const; bool isVertical() const; bool isHorizontal() const; + void moveTab(int, int); protected: virtual void tabInserted(int); @@ -65,7 +66,6 @@ class QETTabBar : public QTabBar { private: bool mustMoveTab(int, int, const QPoint &) const; - void moveTab(int, int); int tabForPressedPosition(const QPoint &); int tabForMovedPosition(const QPoint &); bool posMatchesTabRect(const QRect &, const QPoint &) const; diff --git a/sources/qettabwidget.cpp b/sources/qettabwidget.cpp index c0fd09e6c..ed6d52388 100644 --- a/sources/qettabwidget.cpp +++ b/sources/qettabwidget.cpp @@ -66,6 +66,10 @@ bool QETTabWidget::isMovable() const { #endif } +QTabBar *QETTabWidget::tabBar() const { + return(QTabWidget::tabBar()); +} + /** Gere les evenements rollette sur cette barre d'onglets @param event Evenement rollette diff --git a/sources/qettabwidget.h b/sources/qettabwidget.h index 3efde59d7..b90499888 100644 --- a/sources/qettabwidget.h +++ b/sources/qettabwidget.h @@ -40,6 +40,7 @@ class QETTabWidget : public QTabWidget { public: void setMovable(bool); bool isMovable() const; + QTabBar *tabBar() const; protected: void wheelEvent(QWheelEvent *);