From 3df12cd87674fdfbc2afa21584e1f3e558fa873b Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sat, 13 Apr 2013 15:00:04 -0500 Subject: [PATCH] Add menu items to rearrange taskbar entries Make taskbar drag and drop moving more robust This resolves Bug 1103 --- kcontrol/taskbar/kcmtaskbar.cpp | 3 + kcontrol/taskbar/kcmtaskbarui.ui | 14 +-- kicker/taskbar/taskbar.cpp | 153 ++++++++++++++++++++++++---- kicker/taskbar/taskbar.h | 31 +++++- kicker/taskbar/taskbarcontainer.cpp | 14 +-- kicker/taskbar/taskcontainer.cpp | 68 +++++++++++-- kicker/taskbar/taskcontainer.h | 22 ++-- kicker/taskmanager/taskrmbmenu.cpp | 11 +- kicker/taskmanager/taskrmbmenu.h | 3 +- 9 files changed, 264 insertions(+), 55 deletions(-) diff --git a/kcontrol/taskbar/kcmtaskbar.cpp b/kcontrol/taskbar/kcmtaskbar.cpp index 5bdab1e92..bd98ee3f9 100644 --- a/kcontrol/taskbar/kcmtaskbar.cpp +++ b/kcontrol/taskbar/kcmtaskbar.cpp @@ -172,6 +172,7 @@ TaskbarConfig::TaskbarConfig(TQWidget *parent, const char* name, const TQStringL connect(m_widget->globalConfigReload, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotReloadConfigurationFromGlobals())); connect(m_widget->globalConfigEdit, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotEditGlobalConfiguration())); connect(m_widget->kcfg_UseGlobalSettings, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); + connect(m_widget->kcfg_SortByApp, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); TQFile configFile(locateLocal("config", m_configFileName)); if (!configFile.exists()) @@ -298,6 +299,8 @@ void TaskbarConfig::processLockouts() m_widget->globalConfigEdit->hide(); } } + + m_widget->kcfg_AllowDragAndDropReArrange->setEnabled(!m_widget->kcfg_SortByApp->isChecked()); } void TaskbarConfig::slotReloadConfigurationFromGlobals() diff --git a/kcontrol/taskbar/kcmtaskbarui.ui b/kcontrol/taskbar/kcmtaskbarui.ui index 1f34c32e4..4d655b2a7 100644 --- a/kcontrol/taskbar/kcmtaskbarui.ui +++ b/kcontrol/taskbar/kcmtaskbarui.ui @@ -70,7 +70,7 @@ globalConfigReload - Overwrite current configuration with the current global taskbar configuration + Overwrite current configuration with the current global floating taskbar configuration @@ -78,7 +78,7 @@ globalConfigEdit - Edit global taskbar configuration + Edt global floating taskbar configuration @@ -130,7 +130,7 @@ By default this option is selected. By default, this option is selected and all windows are shown. - + kcfg_AllowDragAndDropReArrange @@ -144,7 +144,7 @@ By default, this option is selected and all windows are shown. Turning this option on will allow tasks on the taskbar to be manually rearranged using drag and drop. - + kcfg_ShowWindowListBtn @@ -216,7 +216,7 @@ By default the taskbar groups windows when it is full. kcfg_ShowTaskStates - + kcfg_ShowOnlyIconified @@ -229,7 +229,7 @@ By default the taskbar groups windows when it is full. By default, this option is not selected and the taskbar will show all windows. - + kcfg_ShowIcon @@ -437,7 +437,7 @@ By default, this option is selected and all windows are shown. true - + kcfg_CycleWheel diff --git a/kicker/taskbar/taskbar.cpp b/kicker/taskbar/taskbar.cpp index 40cc04fe1..ad68f1c8f 100644 --- a/kicker/taskbar/taskbar.cpp +++ b/kicker/taskbar/taskbar.cpp @@ -1295,7 +1295,46 @@ void TaskBar::sortContainersByDesktop(TaskContainer::List& list) } } -int TaskBar::taskMoveHandler(const TQPoint &pos, Task::List taskList) { +TaskMoveDestination::TaskMoveDestination TaskBar::taskMoveCapabilities(TaskContainer* movingContainer) { + TaskMoveDestination::TaskMoveDestination ret = TaskMoveDestination::Null; + + bool before = false; + bool after = false; + bool movingFound = false; + + if (movingContainer) { + // Check to see if there are any visible containers before or after the movingContainer + TaskContainer::Iterator it = containers.begin(); + for (; it != containers.end(); ++it) + { + TaskContainer* c = *it; + if (!c->isVisibleTo(this)) { + continue; + } + if (c == movingContainer) { + movingFound = true; + } + else { + if (movingFound) { + after = true; + } + else { + before = true; + } + } + } + if (before) { + ret = ret | TaskMoveDestination::Left; + } + if (after) { + ret = ret | TaskMoveDestination::Right; + } + } + + return ret; +} + +int TaskBar::taskMoveHandler(TaskMoveDestination::TaskMoveDestination dest, Task::List taskList, const TQPoint pos) { TaskContainer* movingContainer = NULL; TaskContainer* destContainer = NULL; bool movingRight = true; @@ -1304,6 +1343,9 @@ int TaskBar::taskMoveHandler(const TQPoint &pos, Task::List taskList) { for (; it != containers.end(); ++it) { TaskContainer* c = *it; + if (!c->isVisibleTo(this)) { + continue; + } if (c->taskList() == taskList) { movingContainer = c; break; @@ -1311,26 +1353,98 @@ int TaskBar::taskMoveHandler(const TQPoint &pos, Task::List taskList) { } if (movingContainer) { - // Find the best place for the container to go... - it = containers.begin(); - for (; it != containers.end(); ++it) - { - TaskContainer* c = *it; - TQPoint containerPos = c->pos(); - TQSize containerSize = c->size(); - TQRect containerRect(containerPos.x(), containerPos.y(), containerSize.width(), containerSize.height()); - if (containerRect.contains(pos)) { - destContainer = c; - // Figure out if the mobile container is moving towards the end of the container list (i.e. right or down) - for (; it != containers.end(); ++it) - { - if (movingContainer == (*it)) { - movingRight = false; + if (dest == TaskMoveDestination::Position) { + // Find the best place for the container to go... + it = containers.begin(); + for (; it != containers.end(); ++it) + { + TaskContainer* c = *it; + if (!c->isVisibleTo(this)) { + continue; + } + TQPoint containerPos = c->pos(); + TQSize containerSize = c->size(); + TQRect containerRect(containerPos.x(), containerPos.y(), containerSize.width(), containerSize.height()); + if (containerRect.contains(pos)) { + destContainer = c; + // Figure out if the mobile container is moving towards the end of the container list (i.e. right or down) + for (; it != containers.end(); ++it) + { + if (movingContainer == (*it)) { + movingRight = false; + } } + break; } - break; } } + else if (dest == TaskMoveDestination::Beginning) { + // Move to beginning + it = containers.begin(); + while ((it != containers.end()) && (!(*it)->isVisibleTo(this))) { + it++; + } + if (it == containers.end()) { + return false; + } + destContainer = *it; + movingRight = false; + } + else if (dest == TaskMoveDestination::Left) { + // Move left + it = containers.begin(); + while ((it != containers.end()) && (!(*it)->isVisibleTo(this))) { + it++; + } + if (it == containers.end()) { + return false; + } + TaskContainer* prev = *it; + destContainer = prev; + for (; it != containers.end(); ++it) + { + TaskContainer* c = *it; + if (!c->isVisibleTo(this)) { + continue; + } + if (movingContainer == c) { + destContainer = prev; + break; + } + prev = c; + } + movingRight = false; + } + else if (dest == TaskMoveDestination::Right) { + // Move right + it = containers.begin(); + destContainer = NULL; + for (; it != containers.end(); ++it) + { + TaskContainer* c = *it; + if (!c->isVisibleTo(this)) { + continue; + } + if (movingContainer == c) { + if (it != containers.end()) { + it++; + while ((it != containers.end()) && (!(*it)->isVisibleTo(this))) { + it++; + } + } + if ((it != containers.end()) && ((*it)->isVisibleTo(this))) { + destContainer = *it; + } + break; + } + } + movingRight = true; + } + else if (dest == TaskMoveDestination::End) { + // Move to end + destContainer = NULL; + movingRight = true; + } if (destContainer == movingContainer) { return false; @@ -1343,8 +1457,11 @@ int TaskBar::taskMoveHandler(const TQPoint &pos, Task::List taskList) { it = containers.find(destContainer); if ((it != containers.end()) && (movingRight)) { it++; + while ((it != containers.end()) && (!(*it)->isVisibleTo(this))) { + it++; + } } - if (it != containers.end()) { + if ((it != containers.end()) && ((*it)->isVisibleTo(this))) { containers.insert(it, movingContainer); } else { diff --git a/kicker/taskbar/taskbar.h b/kicker/taskbar/taskbar.h index f12ee895d..8c1c42e93 100644 --- a/kicker/taskbar/taskbar.h +++ b/kicker/taskbar/taskbar.h @@ -39,6 +39,34 @@ class Startup; class Task; class TDEGlobalAccel; +namespace TaskMoveDestination +{ + enum TaskMoveDestination + { + Null = 0x00, + Position = 0x01, + Left = 0x02, + Right = 0x04, + Beginning = 0x08, + End = 0x10 + }; + + inline TaskMoveDestination operator|(TaskMoveDestination a, TaskMoveDestination b) + { + return static_cast(static_cast(a) | static_cast(b)); + } + + inline TaskMoveDestination operator&(TaskMoveDestination a, TaskMoveDestination b) + { + return static_cast(static_cast(a) & static_cast(b)); + } + + inline TaskMoveDestination operator~(TaskMoveDestination a) + { + return static_cast(~static_cast(a)); + } +}; + class TaskBar : public Panner { Q_OBJECT @@ -65,7 +93,8 @@ public: KTextShadowEngine *textShadowEngine(); - int taskMoveHandler(const TQPoint &pos, Task::List taskList); + int taskMoveHandler(TaskMoveDestination::TaskMoveDestination dest, Task::List taskList, const TQPoint pos = TQPoint(0,0)); + TaskMoveDestination::TaskMoveDestination taskMoveCapabilities(TaskContainer* movingContainer); public slots: void configure(); diff --git a/kicker/taskbar/taskbarcontainer.cpp b/kicker/taskbar/taskbarcontainer.cpp index 030a565dc..fa105de15 100644 --- a/kicker/taskbar/taskbarcontainer.cpp +++ b/kicker/taskbar/taskbarcontainer.cpp @@ -338,11 +338,9 @@ void TaskBarContainer::dragEnterEvent( TQDragEnterEvent* e ) return; } - if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + if ((e->source()->parent() == taskBar->viewport()) && TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange) && (!READ_MERGED_TASBKAR_SETTING(sortByApp))) { - if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { - e->accept(); - } + e->accept(); } } @@ -359,12 +357,10 @@ void TaskBarContainer::dropEvent( TQDropEvent* e ) return; } - if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + if ((e->source()->parent() == taskBar->viewport()) && TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange) && (!READ_MERGED_TASBKAR_SETTING(sortByApp))) { - if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { - if (taskBar->taskMoveHandler(taskBar->mapFrom(this, e->pos()), TaskDrag::decode(e))) { - e->accept(); - } + if (taskBar->taskMoveHandler(TaskMoveDestination::Position, TaskDrag::decode(e), taskBar->mapFrom(this, e->pos()))) { + e->accept(); } } } \ No newline at end of file diff --git a/kicker/taskbar/taskcontainer.cpp b/kicker/taskbar/taskcontainer.cpp index 484a85659..d29321382 100644 --- a/kicker/taskbar/taskcontainer.cpp +++ b/kicker/taskbar/taskcontainer.cpp @@ -1224,7 +1224,7 @@ void TaskContainer::popupMenu(int action) return; } - m_menu = new TaskRMBMenu(m_filteredTasks, taskBar->showAllWindows()); + m_menu = new TaskRMBMenu(m_filteredTasks, taskBar->showAllWindows(), (READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange))?makeTaskMoveMenu():NULL); } else { @@ -1262,6 +1262,58 @@ void TaskContainer::popupMenu(int action) m_menu = 0; } +TQPopupMenu* TaskContainer::makeTaskMoveMenu() +{ + TaskMoveDestination::TaskMoveDestination capabilities = taskBar->taskMoveCapabilities(this); + + int id; + TQPopupMenu* menu = new TQPopupMenu(); + + menu->setCheckable(false); + + id = menu->insertItem(SmallIconSet("start"), + i18n("Move to Beginning"), + this, TQT_SLOT(slotTaskMoveBeginning())); + menu->setItemEnabled(id, (capabilities & TaskMoveDestination::Left)); + + id = menu->insertItem(SmallIconSet("back"), + i18n("Move Left"), + this, TQT_SLOT(slotTaskMoveLeft())); + menu->setItemEnabled(id, (capabilities & TaskMoveDestination::Left)); + + id = menu->insertItem(SmallIconSet("forward"), + i18n("Move Right"), + this, TQT_SLOT(slotTaskMoveRight())); + menu->setItemEnabled(id, (capabilities & TaskMoveDestination::Right)); + + id = menu->insertItem(SmallIconSet("finish"), + i18n("Move to End"), + this, TQT_SLOT(slotTaskMoveEnd())); + menu->setItemEnabled(id, (capabilities & TaskMoveDestination::Right)); + + return menu; +} + +void TaskContainer::slotTaskMoveBeginning() +{ + taskBar->taskMoveHandler(TaskMoveDestination::Beginning, taskList()); +} + +void TaskContainer::slotTaskMoveLeft() +{ + taskBar->taskMoveHandler(TaskMoveDestination::Left, taskList()); +} + +void TaskContainer::slotTaskMoveRight() +{ + taskBar->taskMoveHandler(TaskMoveDestination::Right, taskList()); +} + +void TaskContainer::slotTaskMoveEnd() +{ + taskBar->taskMoveHandler(TaskMoveDestination::End, taskList()); +} + void TaskContainer::mouseMoveEvent( TQMouseEvent* e ) { kdDebug() << "regular move" << endl; @@ -1399,11 +1451,9 @@ void TaskContainer::dragEnterEvent( TQDragEnterEvent* e ) return; } - if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + if ((e->source()->parent() == this->parent()) && TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange) && (!READ_MERGED_TASBKAR_SETTING(sortByApp))) { - if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { - e->accept(); - } + e->accept(); } // if a dragitem is held for over a taskbutton for two seconds, @@ -1429,12 +1479,10 @@ void TaskContainer::dropEvent( TQDropEvent* e ) return; } - if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + if ((e->source()->parent() == this->parent()) && TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange) && (!READ_MERGED_TASBKAR_SETTING(sortByApp))) { - if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { - if (taskBar->taskMoveHandler(TQWidget::mapTo(taskBar, e->pos()), TaskDrag::decode(e))) { - e->accept(); - } + if (taskBar->taskMoveHandler(TaskMoveDestination::Position, TaskDrag::decode(e), TQWidget::mapTo(taskBar, e->pos()))) { + e->accept(); } } diff --git a/kicker/taskbar/taskcontainer.h b/kicker/taskbar/taskcontainer.h index 857cd6c45..edaf337b4 100644 --- a/kicker/taskbar/taskcontainer.h +++ b/kicker/taskbar/taskcontainer.h @@ -127,22 +127,28 @@ protected slots: void taskChanged(bool geometryChangeOnly); void showMe(); + void slotTaskMoveBeginning(); + void slotTaskMoveLeft(); + void slotTaskMoveRight(); + void slotTaskMoveEnd(); + private: void checkAttention(const Task::Ptr changed_task = NULL); - TQString sid; - TQTimer animationTimer; - TQTimer dragSwitchTimer; - TQTimer attentionTimer; - TQTimer m_paintEventCompressionTimer; + TQPopupMenu* makeTaskMoveMenu(); + TQString sid; + TQTimer animationTimer; + TQTimer dragSwitchTimer; + TQTimer attentionTimer; + TQTimer m_paintEventCompressionTimer; int currentFrame; PixmapList frames; int attentionState; - TQRect iconRect; - TQPixmap animBg; + TQRect iconRect; + TQPixmap animBg; Task::List tasks; Task::List m_filteredTasks; Task::Ptr lastActivated; - TQPopupMenu* m_menu; + TQPopupMenu* m_menu; Startup::Ptr m_startup; ArrowType arrowType; TaskBar* taskBar; diff --git a/kicker/taskmanager/taskrmbmenu.cpp b/kicker/taskmanager/taskrmbmenu.cpp index c910c5f9d..f92719f47 100644 --- a/kicker/taskmanager/taskrmbmenu.cpp +++ b/kicker/taskmanager/taskrmbmenu.cpp @@ -38,10 +38,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "taskrmbmenu.h" #include "taskrmbmenu.moc" -TaskRMBMenu::TaskRMBMenu(const Task::List& theTasks, bool show, TQWidget *parent, const char *name) +TaskRMBMenu::TaskRMBMenu(const Task::List& theTasks, bool show, TQPopupMenu* moveMenu, TQWidget *parent, const char *name) : TQPopupMenu( parent, name ) , tasks( theTasks ) , showAll( show ) + , taskMoveMenu( moveMenu ) { assert(tasks.count() > 0); if (tasks.count() == 1) @@ -57,6 +58,7 @@ TaskRMBMenu::TaskRMBMenu(const Task::List& theTasks, bool show, TQWidget *parent TaskRMBMenu::TaskRMBMenu(Task::Ptr task, bool show, TQWidget *parent, const char *name) : TQPopupMenu( parent, name ) , showAll( show ) + , taskMoveMenu( NULL ) { fillMenu(task); } @@ -106,6 +108,13 @@ void TaskRMBMenu::fillMenu(Task::Ptr t) insertSeparator(); + if (taskMoveMenu) { + taskMoveMenu->reparent(this, taskMoveMenu->getWFlags(), taskMoveMenu->geometry().topLeft(), FALSE); + insertItem(i18n("Move Task Button"), taskMoveMenu); + + insertSeparator(); + } + id = insertItem(SmallIcon("fileclose"), i18n("&Close"), t, TQT_SLOT(close())); setItemEnabled(id, !checkActions || t->info().actionSupported(NET::ActionClose)); } diff --git a/kicker/taskmanager/taskrmbmenu.h b/kicker/taskmanager/taskrmbmenu.h index d95230f9b..76b209ca7 100644 --- a/kicker/taskmanager/taskrmbmenu.h +++ b/kicker/taskmanager/taskrmbmenu.h @@ -32,7 +32,7 @@ class KDE_EXPORT TaskRMBMenu : public TQPopupMenu Q_OBJECT public: - TaskRMBMenu(const Task::List&, bool showAll = true, TQWidget *parent = 0, const char *name = 0); + TaskRMBMenu(const Task::List&, bool showAll = true, TQPopupMenu* moveMenu = NULL, TQWidget *parent = 0, const char *name = 0); TaskRMBMenu(Task::Ptr, bool showAll = true, TQWidget *parent = 0, const char *name = 0); private: @@ -54,6 +54,7 @@ private slots: private: Task::List tasks; bool showAll; + TQPopupMenu* taskMoveMenu; }; #endif