diff --git a/kcontrol/taskbar/kcmtaskbarui.ui b/kcontrol/taskbar/kcmtaskbarui.ui index 3803c1b15..1f34c32e4 100644 --- a/kcontrol/taskbar/kcmtaskbarui.ui +++ b/kcontrol/taskbar/kcmtaskbarui.ui @@ -130,6 +130,20 @@ By default this option is selected. By default, this option is selected and all windows are shown. + + + kcfg_AllowDragAndDropReArrange + + + &Allow taskbar items to be rearranged using drag and drop + + + true + + + Turning this option on will allow tasks on the taskbar to be manually rearranged using drag and drop. + + kcfg_ShowWindowListBtn @@ -144,7 +158,7 @@ By default, this option is selected and all windows are shown. Selecting this option causes the taskbar to display a button that, when clicked, shows a list of all windows in a popup menu. - + kcfg_GroupTasks @@ -164,7 +178,7 @@ You can set the taskbar to <strong>Never</strong> group windows, to By default the taskbar groups windows when it is full. - + groupTasksLabel @@ -175,7 +189,7 @@ By default the taskbar groups windows when it is full. kcfg_ShowTaskStates - + kcfg_ShowTaskStates @@ -191,7 +205,7 @@ By default the taskbar groups windows when it is full. The taskbar can show and/or hide tasks based on their current process state. Select <em>Any</em> to show all tasks regardless of current state. - + showTaskStatesLabel @@ -247,12 +261,12 @@ By default this option is selected. By default, this option is selected and all windows are shown. - + appearance - + textLabel1 @@ -263,7 +277,7 @@ By default, this option is selected and all windows are shown. appearance - + kcfg_UseCustomColors @@ -277,7 +291,7 @@ By default, this option is selected and all windows are shown. true - + layout9 diff --git a/kicker/kicker/buttons/kbutton.cpp b/kicker/kicker/buttons/kbutton.cpp index 2f84badb0..88b664059 100644 --- a/kicker/kicker/buttons/kbutton.cpp +++ b/kicker/kicker/buttons/kbutton.cpp @@ -56,6 +56,9 @@ KButton::KButton( TQWidget* parent ) setButtonText(KickerSettings::kMenuText()); setFont(KickerSettings::buttonFont()); setTextColor(KickerSettings::buttonTextColor()); + setMaximumHeight(30); + setMaximumWidth(widthForHeight(30)); + setCenterButtonInContainer(false); } } @@ -64,6 +67,26 @@ KButton::~KButton() MenuManager::the()->unregisterKButton(this); } +int KButton::widthForHeight(int height) const +{ + if (KickerSettings::showKMenuText()) { + return PanelPopupButton::widthForHeight(30); + } + else { + return PanelPopupButton::widthForHeight(height); + } +} + +int KButton::heightForWidth(int width) const +{ + if (KickerSettings::showKMenuText()) { + return 30; + } + else { + return PanelPopupButton::heightForWidth(width); + } +} + void KButton::properties() { TDEApplication::startServiceByDesktopName("kmenuedit", TQStringList(), diff --git a/kicker/kicker/buttons/kbutton.h b/kicker/kicker/buttons/kbutton.h index a051e9d57..896bf56c2 100644 --- a/kicker/kicker/buttons/kbutton.h +++ b/kicker/kicker/buttons/kbutton.h @@ -41,6 +41,18 @@ public: virtual void properties(); + /** + * Reimplement this to give Kicker a hint for the width of the button + * given a certain height. + */ + virtual int widthForHeight(int height) const; + + /** + * Reimplement this to give Kicker a hint for the height of the button + * given a certain width. + */ + virtual int heightForWidth(int width) const; + protected: virtual TQString tileName() { return "KMenu"; } virtual void initPopup(); diff --git a/kicker/kicker/core/container_button.cpp b/kicker/kicker/core/container_button.cpp index 178d83bae..fa3814bfb 100644 --- a/kicker/kicker/core/container_button.cpp +++ b/kicker/kicker/core/container_button.cpp @@ -145,12 +145,17 @@ void ButtonContainer::embedButton(PanelButton* b) { if (!b) return; - delete _layout; - _layout = new TQVBoxLayout(this); - _button = b; + if (_layout) delete _layout; + _button = b; _button->installEventFilter(this); - _layout->add(_button); + + if (b->centerButtonInContainer()) { + TQVBoxLayout* vbox = new TQVBoxLayout(this); + vbox->addWidget(_button); + _layout = vbox; + } + connect(_button, TQT_SIGNAL(requestSave()), TQT_SIGNAL(requestSave())); connect(_button, TQT_SIGNAL(hideme(bool)), TQT_SLOT(hideRequested(bool))); connect(_button, TQT_SIGNAL(removeme()), TQT_SLOT(removeRequested())); diff --git a/kicker/libkicker/panelbutton.cpp b/kicker/libkicker/panelbutton.cpp index 9f05d1f90..0bd13ac7b 100644 --- a/kicker/libkicker/panelbutton.cpp +++ b/kicker/libkicker/panelbutton.cpp @@ -70,6 +70,7 @@ PanelButton::PanelButton( TQWidget* parent, const char* name, bool forceStandard m_highlight(false), m_changeCursorOverItem(forceStandardCursor?false:true), m_hasAcceptedDrag(false), + m_centerInContainer(true), m_arrowDirection(KPanelExtension::Bottom), m_popupDirection(KPanelApplet::Up), m_iconAlignment(AlignCenter), @@ -938,6 +939,10 @@ bool PanelButton::calculateIconSize() return false; } +void PanelButton::setCenterButtonInContainer(bool center) { + m_centerInContainer = center; +} + void PanelButton::updateKickerTip(KickerTip::Data& data) { data.message = TQStyleSheet::escape(title()); @@ -946,6 +951,11 @@ void PanelButton::updateKickerTip(KickerTip::Data& data) data.direction = popupDirection(); } +bool PanelButton::centerButtonInContainer() +{ + return m_centerInContainer; +} + // // PanelPopupButton class // diff --git a/kicker/libkicker/panelbutton.h b/kicker/libkicker/panelbutton.h index b67bc2b9a..80b26f377 100644 --- a/kicker/libkicker/panelbutton.h +++ b/kicker/libkicker/panelbutton.h @@ -205,6 +205,11 @@ public: */ void updateKickerTip(KickerTip::Data& data); + /** + * @return true if the button should be centered in its parent container, false if not + */ + bool centerButtonInContainer(); + signals: /** * Emitted when the button's icon is changed. @@ -347,6 +352,11 @@ protected: */ bool calculateIconSize(); + /** + * @param center true if the button should be centered in its parent container, false if not + */ + void setCenterButtonInContainer(bool center); + bool m_valid; TQPixmap m_icon; @@ -382,6 +392,7 @@ private: bool m_highlight; bool m_changeCursorOverItem; bool m_hasAcceptedDrag; + bool m_centerInContainer; TQColor m_textColor; TQColor m_tileColor; TQString m_buttonText; diff --git a/kicker/taskbar/taskbar.cpp b/kicker/taskbar/taskbar.cpp index 1e27050f3..40cc04fe1 100644 --- a/kicker/taskbar/taskbar.cpp +++ b/kicker/taskbar/taskbar.cpp @@ -1295,3 +1295,72 @@ void TaskBar::sortContainersByDesktop(TaskContainer::List& list) } } +int TaskBar::taskMoveHandler(const TQPoint &pos, Task::List taskList) { + TaskContainer* movingContainer = NULL; + TaskContainer* destContainer = NULL; + bool movingRight = true; + + TaskContainer::Iterator it = containers.begin(); + for (; it != containers.end(); ++it) + { + TaskContainer* c = *it; + if (c->taskList() == taskList) { + movingContainer = c; + break; + } + } + + 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; + } + } + break; + } + } + + if (destContainer == movingContainer) { + return false; + } + + removeChild(movingContainer); + containers.remove(movingContainer); + + if (destContainer) { + it = containers.find(destContainer); + if ((it != containers.end()) && (movingRight)) { + it++; + } + if (it != containers.end()) { + containers.insert(it, movingContainer); + } + else { + containers.append(movingContainer); + } + } + else { + containers.append(movingContainer); + } + + addChild(movingContainer); + reLayoutEventually(); + emit containerCountChanged(); + + return true; + } + + return false; +} \ No newline at end of file diff --git a/kicker/taskbar/taskbar.h b/kicker/taskbar/taskbar.h index afb59c365..f12ee895d 100644 --- a/kicker/taskbar/taskbar.h +++ b/kicker/taskbar/taskbar.h @@ -65,6 +65,8 @@ public: KTextShadowEngine *textShadowEngine(); + int taskMoveHandler(const TQPoint &pos, Task::List taskList); + public slots: void configure(); void setBackground(); diff --git a/kicker/taskbar/taskbar.kcfg b/kicker/taskbar/taskbar.kcfg index b87c32eaf..320b8a2d6 100644 --- a/kicker/taskbar/taskbar.kcfg +++ b/kicker/taskbar/taskbar.kcfg @@ -11,6 +11,11 @@ Turning this option off will cause the taskbar to ignore the global taskbar configuration, instead using a specific configuration for that particular taskbar. + + true + + Turning this option on will allow tasks on the taskbar to be manually rearranged using drag and drop. + true diff --git a/kicker/taskbar/taskbarcontainer.cpp b/kicker/taskbar/taskbarcontainer.cpp index 5a75f7c15..030a565dc 100644 --- a/kicker/taskbar/taskbarcontainer.cpp +++ b/kicker/taskbar/taskbarcontainer.cpp @@ -74,6 +74,8 @@ TaskBarContainer::TaskBarContainer( bool enableFrame, TQString configFileOverrid settingsObject = new TaskBarSettings(TDESharedConfig::openConfig(configFile)); globalSettingsObject = new TaskBarSettings(TDESharedConfig::openConfig(GLOBAL_TASKBAR_CONFIG_FILE_NAME)); + setAcceptDrops(true); // Always enabled to activate task during drag&drop. + setBackgroundOrigin( AncestorOrigin ); uint margin; @@ -327,3 +329,42 @@ void TaskBarContainer::setBackground() { taskBar->setBackground(); } + +void TaskBarContainer::dragEnterEvent( TQDragEnterEvent* e ) +{ + // ignore all drags other than tasks + if (!TaskDrag::canDecode(e)) + { + return; + } + + if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + { + if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { + e->accept(); + } + } +} + +void TaskBarContainer::dragLeaveEvent( TQDragLeaveEvent* e ) +{ + TQFrame::dragLeaveEvent( e ); +} + +void TaskBarContainer::dropEvent( TQDropEvent* e ) +{ + // ignore all drags other than tasks + if (!TaskDrag::canDecode(e)) + { + return; + } + + if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + { + if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { + if (taskBar->taskMoveHandler(taskBar->mapFrom(this, e->pos()), TaskDrag::decode(e))) { + e->accept(); + } + } + } +} \ No newline at end of file diff --git a/kicker/taskbar/taskbarcontainer.h b/kicker/taskbar/taskbarcontainer.h index fb5f26dd1..7fc13241f 100644 --- a/kicker/taskbar/taskbarcontainer.h +++ b/kicker/taskbar/taskbarcontainer.h @@ -52,6 +52,11 @@ public: TQSize sizeHint( KPanelExtension::Position, TQSize maxSize ) const; void setBackground(); +protected: + void dragEnterEvent(TQDragEnterEvent*); + void dragLeaveEvent(TQDragLeaveEvent*); + void dropEvent(TQDropEvent*); + k_dcop: void configChanged(); diff --git a/kicker/taskbar/taskcontainer.cpp b/kicker/taskbar/taskcontainer.cpp index d63166bb8..484a85659 100644 --- a/kicker/taskbar/taskcontainer.cpp +++ b/kicker/taskbar/taskcontainer.cpp @@ -1393,12 +1393,19 @@ void TaskContainer::publishIconGeometry( TQPoint global ) void TaskContainer::dragEnterEvent( TQDragEnterEvent* e ) { - // ignore task drags and applet drags - if (TaskDrag::canDecode(e) || PanelDrag::canDecode(e)) + // ignore applet drags + if (PanelDrag::canDecode(e)) { return; } + if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + { + if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { + e->accept(); + } + } + // if a dragitem is held for over a taskbutton for two seconds, // activate corresponding window if (m_filteredTasks.isEmpty()) @@ -1415,6 +1422,27 @@ void TaskContainer::dragEnterEvent( TQDragEnterEvent* e ) TQToolButton::dragEnterEvent( e ); } +void TaskContainer::dropEvent( TQDropEvent* e ) +{ + // Ignore all drops except tasks + if (!TaskDrag::canDecode(e)) { + return; + } + + if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + { + if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { + if (taskBar->taskMoveHandler(TQWidget::mapTo(taskBar, e->pos()), TaskDrag::decode(e))) { + e->accept(); + } + } + } + + dragSwitchTimer.stop(); + + TQToolButton::dropEvent( e ); +} + void TaskContainer::dragLeaveEvent( TQDragLeaveEvent* e ) { dragSwitchTimer.stop(); diff --git a/kicker/taskbar/taskcontainer.h b/kicker/taskbar/taskcontainer.h index b7016477e..857cd6c45 100644 --- a/kicker/taskbar/taskcontainer.h +++ b/kicker/taskbar/taskcontainer.h @@ -87,9 +87,11 @@ public: void updateKickerTip(KickerTip::Data&); void finish(); - + void setBackground(); - + + Task::List taskList() const { return tasks; } + public slots: void updateNow(); @@ -105,6 +107,7 @@ protected: void mouseMoveEvent(TQMouseEvent*); void dragEnterEvent(TQDragEnterEvent*); void dragLeaveEvent(TQDragLeaveEvent*); + void dropEvent(TQDropEvent*); void enterEvent(TQEvent*); void leaveEvent(TQEvent*); bool startDrag(const TQPoint& pos);