add more spacing
[personal-kdebase.git] / workspace / kwin / kcmkwin / kwinrules / ruleswidget.cpp
blob9b6b690a6dec4cf0e70413c48d8c2bdf7d25706f
1 /*
2 * Copyright (c) 2004 Lubos Lunak <l.lunak@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "ruleswidget.h"
21 #include <klineedit.h>
22 #include <krestrictedline.h>
23 #include <kcombobox.h>
24 #include <QCheckBox>
25 #include <kpushbutton.h>
26 #include <QLabel>
27 #include <kwindowsystem.h>
28 #include <klocale.h>
29 #include <QRegExp>
31 #include <assert.h>
32 #include <kmessagebox.h>
33 #include <QTabWidget>
34 #include <QTimer>
36 #include "../../rules.h"
38 #include "detectwidget.h"
40 namespace KWin
43 #define SETUP( var, type ) \
44 connect( enable_##var, SIGNAL( toggled( bool )), rule_##var, SLOT( setEnabled( bool ))); \
45 connect( enable_##var, SIGNAL( toggled( bool )), this, SLOT( updateEnable##var())); \
46 connect( rule_##var, SIGNAL( activated( int )), this, SLOT( updateEnable##var())); \
47 enable_##var->setWhatsThis( enableDesc ); \
48 rule_##var->setWhatsThis( type##RuleDesc );
50 RulesWidget::RulesWidget( QWidget* parent )
51 : detect_dlg( NULL )
53 setupUi(this);
55 QString enableDesc =
56 i18n( "Enable this checkbox to alter this window property for the specified window(s)." );
57 QString setRuleDesc =
58 i18n( "Specify how the window property should be affected:<ul>"
59 "<li><em>Do Not Affect:</em> The window property will not be affected and therefore"
60 " the default handling for it will be used. Specifying this will block more generic"
61 " window settings from taking effect.</li>"
62 "<li><em>Apply Initially:</em> The window property will be only set to the given value"
63 " after the window is created. No further changes will be affected.</li>"
64 "<li><em>Remember:</em> The value of the window property will be remembered and every time"
65 " time the window is created, the last remembered value will be applied.</li>"
66 "<li><em>Force:</em> The window property will be always forced to the given value.</li>"
67 "<li><em>Apply Now:</em> The window property will be set to the given value immediately"
68 " and will not be affected later (this action will be deleted afterwards).</li>"
69 "<li><em>Force temporarily:</em> The window property will be forced to the given value"
70 " until it is hidden (this action will be deleted after the window is hidden).</li>"
71 "</ul>" );
72 QString forceRuleDesc =
73 i18n( "Specify how the window property should be affected:<ul>"
74 "<li><em>Do Not Affect:</em> The window property will not be affected and therefore"
75 " the default handling for it will be used. Specifying this will block more generic"
76 " window settings from taking effect.</li>"
77 "<li><em>Force:</em> The window property will be always forced to the given value.</li>"
78 "<li><em>Force temporarily:</em> The window property will be forced to the given value"
79 " until it is hidden (this action will be deleted after the window is hidden).</li>"
80 "</ul>" );
81 // window tabs have enable signals done in designer
82 // geometry tab
83 SETUP( position, set );
84 SETUP( size, set );
85 SETUP( desktop, set );
86 SETUP( maximizehoriz, set );
87 SETUP( maximizevert, set );
88 SETUP( minimize, set );
89 SETUP( shade, set );
90 SETUP( fullscreen, set );
91 SETUP( placement, force );
92 // preferences tab
93 SETUP( above, set );
94 SETUP( below, set );
95 SETUP( noborder, set );
96 SETUP( skiptaskbar, set );
97 SETUP( skippager, set );
98 SETUP( acceptfocus, force );
99 SETUP( closeable, force );
100 SETUP( opacityactive, force );
101 SETUP( opacityinactive, force );
102 SETUP( shortcut, force );
103 // workarounds tab
104 SETUP( fsplevel, force );
105 SETUP( moveresizemode, force );
106 SETUP( type, force );
107 SETUP( ignoreposition, force );
108 SETUP( minsize, force );
109 SETUP( maxsize, force );
110 SETUP( strictgeometry, force );
111 SETUP( disableglobalshortcuts, force );
112 int i;
113 for( i = 1;
114 i <= KWindowSystem::numberOfDesktops();
115 ++i )
116 desktop->addItem( QString::number( i ).rightJustified( 2 ) + ':' + KWindowSystem::desktopName( i ));
117 desktop->addItem( i18n( "All Desktops" ));
120 #undef SETUP
122 #define UPDATE_ENABLE_SLOT( var ) \
123 void RulesWidget::updateEnable##var() \
125 /* leave the label readable label_##var->setEnabled( enable_##var->isChecked() && rule_##var->currentIndex() != 0 );*/ \
126 Ui::RulesWidgetBase::var->setEnabled( enable_##var->isChecked() && rule_##var->currentIndex() != 0 ); \
129 // geometry tab
130 UPDATE_ENABLE_SLOT( position )
131 UPDATE_ENABLE_SLOT( size )
132 UPDATE_ENABLE_SLOT( desktop )
133 UPDATE_ENABLE_SLOT( maximizehoriz )
134 UPDATE_ENABLE_SLOT( maximizevert )
135 UPDATE_ENABLE_SLOT( minimize )
136 UPDATE_ENABLE_SLOT( shade )
137 UPDATE_ENABLE_SLOT( fullscreen )
138 UPDATE_ENABLE_SLOT( placement )
139 // preferences tab
140 UPDATE_ENABLE_SLOT( above )
141 UPDATE_ENABLE_SLOT( below )
142 UPDATE_ENABLE_SLOT( noborder )
143 UPDATE_ENABLE_SLOT( skiptaskbar )
144 UPDATE_ENABLE_SLOT( skippager )
145 UPDATE_ENABLE_SLOT( acceptfocus )
146 UPDATE_ENABLE_SLOT( closeable )
147 UPDATE_ENABLE_SLOT( opacityactive )
148 UPDATE_ENABLE_SLOT( opacityinactive )
149 void RulesWidget::updateEnableshortcut()
151 shortcut->setEnabled( enable_shortcut->isChecked() && rule_shortcut->currentIndex() != 0 );
152 shortcut_edit->setEnabled( enable_shortcut->isChecked() && rule_shortcut->currentIndex() != 0 );
154 // workarounds tab
155 UPDATE_ENABLE_SLOT( fsplevel )
156 UPDATE_ENABLE_SLOT( moveresizemode )
157 UPDATE_ENABLE_SLOT( type )
158 UPDATE_ENABLE_SLOT( ignoreposition )
159 UPDATE_ENABLE_SLOT( minsize )
160 UPDATE_ENABLE_SLOT( maxsize )
161 UPDATE_ENABLE_SLOT( strictgeometry )
162 UPDATE_ENABLE_SLOT( disableglobalshortcuts )
164 #undef UPDATE_ENABLE_SLOT
166 static const int set_rule_to_combo[] =
168 0, // Unused
169 0, // Don't Affect
170 3, // Force
171 1, // Apply
172 2, // Remember
173 4, // ApplyNow
174 5 // ForceTemporarily
177 static const Rules::SetRule combo_to_set_rule[] =
179 ( Rules::SetRule )Rules::DontAffect,
180 ( Rules::SetRule )Rules::Apply,
181 ( Rules::SetRule )Rules::Remember,
182 ( Rules::SetRule )Rules::Force,
183 ( Rules::SetRule )Rules::ApplyNow,
184 ( Rules::SetRule )Rules::ForceTemporarily
187 static const int force_rule_to_combo[] =
189 0, // Unused
190 0, // Don't Affect
191 1, // Force
192 0, // Apply
193 0, // Remember
194 0, // ApplyNow
195 2 // ForceTemporarily
198 static const Rules::ForceRule combo_to_force_rule[] =
200 ( Rules::ForceRule )Rules::DontAffect,
201 ( Rules::ForceRule )Rules::Force,
202 ( Rules::ForceRule )Rules::ForceTemporarily
205 static QString positionToStr( const QPoint& p )
207 if( p == invalidPoint )
208 return QString();
209 return QString::number( p.x()) + ',' + QString::number( p.y());
212 static QPoint strToPosition( const QString& str )
213 { // two numbers, with + or -, separated by any of , x X :
214 QRegExp reg( "\\s*([+-]?[0-9]*)\\s*[,xX:]\\s*([+-]?[0-9]*)\\s*" );
215 if( !reg.exactMatch( str ))
216 return invalidPoint;
217 return QPoint( reg.cap( 1 ).toInt(), reg.cap( 2 ).toInt());
220 static QString sizeToStr( const QSize& s )
222 if( !s.isValid())
223 return QString();
224 return QString::number( s.width()) + ',' + QString::number( s.height());
227 static QSize strToSize( const QString& str )
228 { // two numbers, with + or -, separated by any of , x X :
229 QRegExp reg( "\\s*([+-]?[0-9]*)\\s*[,xX:]\\s*([+-]?[0-9]*)\\s*" );
230 if( !reg.exactMatch( str ))
231 return QSize();
232 return QSize( reg.cap( 1 ).toInt(), reg.cap( 2 ).toInt());
235 //used for opacity settings
236 static QString intToStr( const int& s )
238 if( s < 1 || s > 100 )
239 return QString();
240 return QString::number(s);
243 static int strToInt( const QString& str )
245 int tmp = str.toInt();
246 if( tmp < 1 || tmp > 100 )
247 return 100;
248 return tmp;
251 int RulesWidget::desktopToCombo( int d ) const
253 if( d >= 1 && d < desktop->count())
254 return d - 1;
255 return desktop->count() - 1; // on all desktops
258 int RulesWidget::comboToDesktop( int val ) const
260 if( val == desktop->count() - 1 )
261 return NET::OnAllDesktops;
262 return val + 1;
265 static int placementToCombo( Placement::Policy placement )
267 static const int conv[] =
269 1, // NoPlacement
270 0, // Default
271 0, // Unknown
272 6, // Random
273 2, // Smart
274 4, // Cascade
275 5, // Centered
276 7, // ZeroCornered
277 8, // UnderMouse
278 9, // OnMainWindow
279 3 // Maximizing
281 return conv[ placement ];
284 static Placement::Policy comboToPlacement( int val )
286 static const Placement::Policy conv[] =
288 Placement::Default,
289 Placement::NoPlacement,
290 Placement::Smart,
291 Placement::Maximizing,
292 Placement::Cascade,
293 Placement::Centered,
294 Placement::Random,
295 Placement::ZeroCornered,
296 Placement::UnderMouse,
297 Placement::OnMainWindow
298 // no Placement::Unknown
300 return conv[ val ];
303 static int moveresizeToCombo( Options::MoveResizeMode mode )
305 return mode == Options::Opaque ? 0 : 1;
308 static Options::MoveResizeMode comboToMoveResize( int val )
310 return val == 0 ? Options::Opaque : Options::Transparent;
313 static int typeToCombo( NET::WindowType type )
315 if( type < NET::Normal || type > NET::Splash )
316 return 0; // Normal
317 static const int conv[] =
319 0, // Normal
320 7, // Desktop
321 3, // Dock
322 4, // Toolbar
323 5, // Menu
324 1, // Dialog
325 8, // Override
326 9, // TopMenu
327 2, // Utility
328 6 // Splash
330 return conv[ type ];
333 static NET::WindowType comboToType( int val )
335 static const NET::WindowType conv[] =
337 NET::Normal,
338 NET::Dialog,
339 NET::Utility,
340 NET::Dock,
341 NET::Toolbar,
342 NET::Menu,
343 NET::Splash,
344 NET::Desktop,
345 NET::Override,
346 NET::TopMenu
348 return conv[ val ];
351 #define GENERIC_RULE( var, func, Type, type, uimethod, uimethod0 ) \
352 if( rules->var##rule == Rules::Unused##Type##Rule ) \
354 enable_##var->setChecked( false ); \
355 rule_##var->setCurrentIndex( 0 ); \
356 Ui::RulesWidgetBase::var->uimethod0; \
357 updateEnable##var(); \
359 else \
361 enable_##var->setChecked( true ); \
362 rule_##var->setCurrentIndex( type##_rule_to_combo[ rules->var##rule ] ); \
363 Ui::RulesWidgetBase::var->uimethod( func( rules->var )); \
364 updateEnable##var(); \
367 #define CHECKBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, setChecked, setChecked( false ))
368 #define LINEEDIT_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, setText, setText( "" ))
369 #define COMBOBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, setCurrentIndex, setCurrentIndex( 0 ))
370 #define CHECKBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, setChecked, setChecked( false ))
371 #define LINEEDIT_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, setText, setText( "" ))
372 #define COMBOBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, setCurrentIndex, setCurrentIndex( 0 ))
374 void RulesWidget::setRules( Rules* rules )
376 Rules tmp;
377 if( rules == NULL )
378 rules = &tmp; // empty
379 description->setText( rules->description );
380 wmclass->setText( rules->wmclass );
381 whole_wmclass->setChecked( rules->wmclasscomplete );
382 wmclass_match->setCurrentIndex( rules->wmclassmatch );
383 wmclassMatchChanged();
384 role->setText( rules->windowrole );
385 role_match->setCurrentIndex( rules->windowrolematch );
386 roleMatchChanged();
387 types->item(0)->setSelected( rules->types & NET::NormalMask );
388 types->item(1)->setSelected( rules->types & NET::DialogMask );
389 types->item(2)->setSelected( rules->types & NET::UtilityMask );
390 types->item(3)->setSelected( rules->types & NET::DockMask );
391 types->item(4)->setSelected( rules->types & NET::ToolbarMask );
392 types->item(5)->setSelected( rules->types & NET::MenuMask );
393 types->item(6)->setSelected( rules->types & NET::SplashMask );
394 types->item(7)->setSelected( rules->types & NET::DesktopMask );
395 types->item(8)->setSelected( rules->types & NET::OverrideMask );
396 types->item(9)->setSelected( rules->types & NET::TopMenuMask );
397 title->setText( rules->title );
398 title_match->setCurrentIndex( rules->titlematch );
399 titleMatchChanged();
400 extra->setText( rules->extrarole );
401 extra_match->setCurrentIndex( rules->extrarolematch );
402 extraMatchChanged();
403 machine->setText( rules->clientmachine );
404 machine_match->setCurrentIndex( rules->clientmachinematch );
405 machineMatchChanged();
406 LINEEDIT_SET_RULE( position, positionToStr );
407 LINEEDIT_SET_RULE( size, sizeToStr );
408 COMBOBOX_SET_RULE( desktop, desktopToCombo );
409 CHECKBOX_SET_RULE( maximizehoriz, );
410 CHECKBOX_SET_RULE( maximizevert, );
411 CHECKBOX_SET_RULE( minimize, );
412 CHECKBOX_SET_RULE( shade, );
413 CHECKBOX_SET_RULE( fullscreen, );
414 COMBOBOX_FORCE_RULE( placement, placementToCombo );
415 CHECKBOX_SET_RULE( above, );
416 CHECKBOX_SET_RULE( below, );
417 CHECKBOX_SET_RULE( noborder, );
418 CHECKBOX_SET_RULE( skiptaskbar, );
419 CHECKBOX_SET_RULE( skippager, );
420 CHECKBOX_FORCE_RULE( acceptfocus, );
421 CHECKBOX_FORCE_RULE( closeable, );
422 LINEEDIT_FORCE_RULE( opacityactive, intToStr );
423 LINEEDIT_FORCE_RULE( opacityinactive, intToStr );
424 LINEEDIT_SET_RULE( shortcut, );
425 COMBOBOX_FORCE_RULE( fsplevel, );
426 COMBOBOX_FORCE_RULE( moveresizemode, moveresizeToCombo );
427 COMBOBOX_FORCE_RULE( type, typeToCombo );
428 CHECKBOX_FORCE_RULE( ignoreposition, );
429 LINEEDIT_FORCE_RULE( minsize, sizeToStr );
430 LINEEDIT_FORCE_RULE( maxsize, sizeToStr );
431 CHECKBOX_FORCE_RULE( strictgeometry, );
432 CHECKBOX_FORCE_RULE( disableglobalshortcuts, );
435 #undef GENERIC_RULE
436 #undef CHECKBOX_SET_RULE
437 #undef LINEEDIT_SET_RULE
438 #undef COMBOBOX_SET_RULE
439 #undef CHECKBOX_FORCE_RULE
440 #undef LINEEDIT_FORCE_RULE
441 #undef COMBOBOX_FORCE_RULE
443 #define GENERIC_RULE( var, func, Type, type, uimethod ) \
444 if( enable_##var->isChecked() && rule_##var->currentIndex() >= 0) \
446 rules->var##rule = combo_to_##type##_rule[ rule_##var->currentIndex() ]; \
447 rules->var = func( Ui::RulesWidgetBase::var->uimethod()); \
449 else \
450 rules->var##rule = Rules::Unused##Type##Rule;
452 #define CHECKBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, isChecked )
453 #define LINEEDIT_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, text )
454 #define COMBOBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, currentIndex )
455 #define CHECKBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, isChecked )
456 #define LINEEDIT_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, text )
457 #define COMBOBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, currentIndex )
459 Rules* RulesWidget::rules() const
461 Rules* rules = new Rules();
462 rules->description = description->text();
463 rules->wmclass = wmclass->text().toUtf8();
464 rules->wmclasscomplete = whole_wmclass->isChecked();
465 rules->wmclassmatch = static_cast< Rules::StringMatch >( wmclass_match->currentIndex());
466 rules->windowrole = role->text().toUtf8();
467 rules->windowrolematch = static_cast< Rules::StringMatch >( role_match->currentIndex());
468 rules->types = 0;
469 bool all_types = true;
470 for( int i = 0;
471 i < types->count();
472 ++i )
473 if( !types->item(i)->isSelected())
474 all_types = false;
475 if( all_types ) // if all types are selected, use AllTypesMask (for future expansion)
476 rules->types = NET::AllTypesMask;
477 else
479 rules->types |= types->item(0)->isSelected() ? NET::NormalMask : 0;
480 rules->types |= types->item(1)->isSelected() ? NET::DialogMask : 0;
481 rules->types |= types->item(2)->isSelected() ? NET::UtilityMask : 0;
482 rules->types |= types->item(3)->isSelected() ? NET::DockMask : 0;
483 rules->types |= types->item(4)->isSelected() ? NET::ToolbarMask : 0;
484 rules->types |= types->item(5)->isSelected() ? NET::MenuMask : 0;
485 rules->types |= types->item(6)->isSelected() ? NET::SplashMask : 0;
486 rules->types |= types->item(7)->isSelected() ? NET::DesktopMask : 0;
487 rules->types |= types->item(8)->isSelected() ? NET::OverrideMask : 0;
488 rules->types |= types->item(9)->isSelected() ? NET::TopMenuMask : 0;
490 rules->title = title->text();
491 rules->titlematch = static_cast< Rules::StringMatch >( title_match->currentIndex());
492 rules->extrarole = extra->text().toUtf8();
493 rules->extrarolematch = static_cast< Rules::StringMatch >( extra_match->currentIndex());
494 rules->clientmachine = machine->text().toUtf8();
495 rules->clientmachinematch = static_cast< Rules::StringMatch >( machine_match->currentIndex());
496 LINEEDIT_SET_RULE( position, strToPosition );
497 LINEEDIT_SET_RULE( size, strToSize );
498 COMBOBOX_SET_RULE( desktop, comboToDesktop );
499 CHECKBOX_SET_RULE( maximizehoriz, );
500 CHECKBOX_SET_RULE( maximizevert, );
501 CHECKBOX_SET_RULE( minimize, );
502 CHECKBOX_SET_RULE( shade, );
503 CHECKBOX_SET_RULE( fullscreen, );
504 COMBOBOX_FORCE_RULE( placement, comboToPlacement );
505 CHECKBOX_SET_RULE( above, );
506 CHECKBOX_SET_RULE( below, );
507 CHECKBOX_SET_RULE( noborder, );
508 CHECKBOX_SET_RULE( skiptaskbar, );
509 CHECKBOX_SET_RULE( skippager, );
510 CHECKBOX_FORCE_RULE( acceptfocus, );
511 CHECKBOX_FORCE_RULE( closeable, );
512 LINEEDIT_FORCE_RULE( opacityactive, strToInt );
513 LINEEDIT_FORCE_RULE( opacityinactive, strToInt );
514 LINEEDIT_SET_RULE( shortcut, );
515 COMBOBOX_FORCE_RULE( fsplevel, );
516 COMBOBOX_FORCE_RULE( moveresizemode, comboToMoveResize );
517 COMBOBOX_FORCE_RULE( type, comboToType );
518 CHECKBOX_FORCE_RULE( ignoreposition, );
519 LINEEDIT_FORCE_RULE( minsize, strToSize );
520 LINEEDIT_FORCE_RULE( maxsize, strToSize );
521 CHECKBOX_FORCE_RULE( strictgeometry, );
522 CHECKBOX_FORCE_RULE( disableglobalshortcuts, );
523 return rules;
526 #undef GENERIC_RULE
527 #undef CHECKBOX_SET_RULE
528 #undef LINEEDIT_SET_RULE
529 #undef COMBOBOX_SET_RULE
530 #undef CHECKBOX_FORCE_RULE
531 #undef LINEEDIT_FORCE_RULE
532 #undef COMBOBOX_FORCE_RULE
534 #define STRING_MATCH_COMBO( type ) \
535 void RulesWidget::type##MatchChanged() \
537 edit_reg_##type->setEnabled( type##_match->currentIndex() == Rules::RegExpMatch ); \
538 type->setEnabled( type##_match->currentIndex() != Rules::UnimportantMatch ); \
541 STRING_MATCH_COMBO( wmclass )
542 STRING_MATCH_COMBO( role )
543 STRING_MATCH_COMBO( title )
544 STRING_MATCH_COMBO( extra )
545 STRING_MATCH_COMBO( machine )
547 #undef STRING_MATCH_COMBO
549 void RulesWidget::detectClicked()
551 assert( detect_dlg == NULL );
552 detect_dlg = new DetectDialog;
553 connect( detect_dlg, SIGNAL( detectionDone( bool )), this, SLOT( detected( bool )));
554 detect_dlg->detect( 0 );
557 void RulesWidget::detected( bool ok )
559 if( ok )
561 wmclass->setText( detect_dlg->selectedClass());
562 wmclass_match->setCurrentIndex( Rules::ExactMatch );
563 wmclassMatchChanged(); // grrr
564 whole_wmclass->setChecked( detect_dlg->selectedWholeClass());
565 role->setText( detect_dlg->selectedRole());
566 role_match->setCurrentIndex( detect_dlg->selectedRole().isEmpty()
567 ? Rules::UnimportantMatch : Rules::ExactMatch );
568 roleMatchChanged();
569 if( detect_dlg->selectedWholeApp())
571 for( int i = 0;
572 i < types->count();
573 ++i )
574 types->item(i)->setSelected( true );
576 else
578 NET::WindowType type = detect_dlg->selectedType();
579 for( int i = 0;
580 i < types->count();
581 ++i )
582 types->item(i)->setSelected( false );
583 types->item( typeToCombo(type) )->setSelected( true );
585 title->setText( detect_dlg->selectedTitle());
586 title_match->setCurrentIndex( detect_dlg->titleMatch());
587 titleMatchChanged();
588 machine->setText( detect_dlg->selectedMachine());
589 machine_match->setCurrentIndex( Rules::UnimportantMatch );
590 machineMatchChanged();
591 // prefill values from to window to settings which already set
592 const KWindowInfo& info = detect_dlg->windowInfo();
593 prefillUnusedValues( info );
595 delete detect_dlg;
596 detect_dlg = NULL;
597 detect_dlg_ok = ok;
600 #define GENERIC_PREFILL( var, func, info, uimethod ) \
601 if( !enable_##var->isChecked()) \
603 Ui::RulesWidgetBase::var->uimethod( func( info )); \
606 #define CHECKBOX_PREFILL( var, func, info ) GENERIC_PREFILL( var, func, info, setChecked )
607 #define LINEEDIT_PREFILL( var, func, info ) GENERIC_PREFILL( var, func, info, setText )
608 #define COMBOBOX_PREFILL( var, func, info ) GENERIC_PREFILL( var, func, info, setCurrentIndex )
610 void RulesWidget::prefillUnusedValues( const KWindowInfo& info )
612 LINEEDIT_PREFILL( position, positionToStr, info.frameGeometry().topLeft() );
613 LINEEDIT_PREFILL( size, sizeToStr, info.frameGeometry().size() );
614 COMBOBOX_PREFILL( desktop, desktopToCombo, info.desktop() );
615 CHECKBOX_PREFILL( maximizehoriz,, info.state() & NET::MaxHoriz );
616 CHECKBOX_PREFILL( maximizevert,, info.state() & NET::MaxVert );
617 CHECKBOX_PREFILL( minimize,, info.isMinimized() );
618 CHECKBOX_PREFILL( shade,, info.state() & NET::Shaded );
619 CHECKBOX_PREFILL( fullscreen,, info.state() & NET::FullScreen );
620 //COMBOBOX_PREFILL( placement, placementToCombo );
621 CHECKBOX_PREFILL( above,, info.state() & NET::KeepAbove );
622 CHECKBOX_PREFILL( below,, info.state() & NET::KeepBelow );
623 // noborder is only internal KWin information, so let's guess
624 CHECKBOX_PREFILL( noborder,, info.frameGeometry() == info.geometry() );
625 CHECKBOX_PREFILL( skiptaskbar,, info.state() & NET::SkipTaskbar );
626 CHECKBOX_PREFILL( skippager,, info.state() & NET::SkipPager );
627 //CHECKBOX_PREFILL( acceptfocus, );
628 //CHECKBOX_PREFILL( closeable, );
629 LINEEDIT_PREFILL( opacityactive, intToStr, 100 /*get the actual opacity somehow*/);
630 LINEEDIT_PREFILL( opacityinactive, intToStr, 100 /*get the actual opacity somehow*/);
631 //LINEEDIT_PREFILL( shortcut, );
632 //COMBOBOX_PREFILL( fsplevel, );
633 //COMBOBOX_PREFILL( moveresizemode, moveresizeToCombo );
634 COMBOBOX_PREFILL( type, typeToCombo, info.windowType( SUPPORTED_MANAGED_WINDOW_TYPES_MASK ) );
635 //CHECKBOX_PREFILL( ignoreposition, );
636 LINEEDIT_PREFILL( minsize, sizeToStr, info.frameGeometry().size() );
637 LINEEDIT_PREFILL( maxsize, sizeToStr, info.frameGeometry().size() );
638 //CHECKBOX_PREFILL( strictgeometry, );
639 //CHECKBOX_PREFILL( disableglobalshortcuts, );
642 #undef GENERIC_PREFILL
643 #undef CHECKBOX_PREFILL
644 #undef LINEEDIT_PREFILL
645 #undef COMBOBOX_PREFILL
647 bool RulesWidget::finalCheck()
649 if( description->text().isEmpty())
651 if( !wmclass->text().isEmpty())
652 description->setText( i18n( "Settings for %1", wmclass->text()));
653 else
654 description->setText( i18n( "Unnamed entry" ));
656 bool all_types = true;
657 for( int i = 0;
658 i < types->count();
659 ++i )
660 if( !types->item(i)->isSelected())
661 all_types = false;
662 if( wmclass_match->currentIndex() == Rules::UnimportantMatch && all_types )
664 if( KMessageBox::warningContinueCancel( window(),
665 i18n( "You have specified the window class as unimportant.\n"
666 "This means the settings will possibly apply to windows from all applications. "
667 "If you really want to create a generic setting, it is recommended you at least "
668 "limit the window types to avoid special window types." )) != KMessageBox::Continue )
669 return false;
671 return true;
674 void RulesWidget::prepareWindowSpecific( WId window )
676 tabs->setCurrentIndex( 2 ); // geometry tab, skip tabs for window identification
677 KWindowInfo info( window, -1U, -1U ); // read everything
678 prefillUnusedValues( info );
681 void RulesWidget::shortcutEditClicked()
683 EditShortcutDialog dlg( window());
684 dlg.setShortcut( shortcut->text());
685 if( dlg.exec() == QDialog::Accepted )
686 shortcut->setText( dlg.shortcut());
689 RulesDialog::RulesDialog( QWidget* parent, const char* name )
690 : KDialog( parent )
692 setObjectName( name );
693 setModal( true );
694 setCaption( i18n( "Edit Window-Specific Settings" ) );
695 setButtons( Ok | Cancel );
697 widget = new RulesWidget( this );
698 setMainWidget( widget );
701 // window is set only for Alt+F3/Window-specific settings, because the dialog
702 // is then related to one specific window
703 Rules* RulesDialog::edit( Rules* r, WId window, bool show_hints )
705 rules = r;
706 widget->setRules( rules );
707 if( window != 0 )
708 widget->prepareWindowSpecific( window );
709 if( show_hints )
710 QTimer::singleShot( 0, this, SLOT( displayHints()));
711 exec();
712 return rules;
715 void RulesDialog::displayHints()
717 QString str = "<qt><p>";
718 str += i18n( "This configuration dialog allows altering settings only for the selected window"
719 " or application. Find the setting you want to affect, enable the setting using the checkbox,"
720 " select in what way the setting should be affected and to which value." );
721 #if 0 // maybe later
722 str += "</p><p>" + i18n( "Consult the documentation for more details." );
723 #endif
724 str += "</p></qt>";
725 KMessageBox::information( this, str, QString(), "displayhints" );
728 void RulesDialog::accept()
730 if( !widget->finalCheck())
731 return;
732 rules = widget->rules();
733 KDialog::accept();
736 EditShortcut::EditShortcut( QWidget* parent )
737 : QWidget( parent )
739 setupUi( this );
742 void EditShortcut::editShortcut()
744 ShortcutDialog dlg( QKeySequence( shortcut->text()), window());
745 if( dlg.exec() == QDialog::Accepted )
746 shortcut->setText( dlg.shortcut().toString());
749 void EditShortcut::clearShortcut()
751 shortcut->setText( QLatin1String("") );
754 EditShortcutDialog::EditShortcutDialog( QWidget* parent, const char* name )
755 : KDialog( parent )
757 setObjectName( name );
758 setModal( true );
759 setCaption( i18n( "Edit Shortcut" ) );
760 setButtons( Ok | Cancel );
762 widget = new EditShortcut( this );
763 setMainWidget( widget );
766 void EditShortcutDialog::setShortcut( const QString& cut )
768 widget->shortcut->setText( cut );
771 QString EditShortcutDialog::shortcut() const
773 return widget->shortcut->text();
776 ShortcutDialog::ShortcutDialog( const QKeySequence& cut, QWidget* parent )
777 : KDialog( parent )
778 , widget( new KKeySequenceWidget( this ))
780 widget->setKeySequence( cut );
781 // It's a global shortcut so don't allow multikey shortcuts
782 widget->setMultiKeyShortcutsAllowed(false);
783 setMainWidget( widget );
786 void ShortcutDialog::accept()
788 QKeySequence seq = shortcut();
789 if( !seq.isEmpty())
791 if( seq[0] == Qt::Key_Escape )
793 reject();
794 return;
796 if( seq[0] == Qt::Key_Space
797 || (seq[0] & Qt::KeyboardModifierMask) == 0 )
798 { // clear
799 widget->clearKeySequence();
800 KDialog::accept();
801 return;
804 KDialog::accept();
807 QKeySequence ShortcutDialog::shortcut() const
809 return widget->keySequence();
812 } // namespace
814 #include "ruleswidget.moc"