PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/kdepim-4.3.4/kmail/messagelistview/core/configurethemesdialog.cpp

#
C++ | 369 lines | 276 code | 72 blank | 21 comment | 33 complexity | 29b96cb145e4b8722ac6f02e5e4a4138 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0
  1. /******************************************************************************
  2. *
  3. * Copyright 2008 Szymon Tomasz Stefanek <pragma@kvirc.net>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. *
  19. *******************************************************************************/
  20. #include "messagelistview/core/configurethemesdialog.h"
  21. #include "messagelistview/core/themeeditor.h"
  22. #include "messagelistview/core/theme.h"
  23. #include "messagelistview/core/manager.h"
  24. #include <QGridLayout>
  25. #include <QPushButton>
  26. #include <QFrame>
  27. #include <QHash>
  28. #include <KLocale>
  29. #include <KIconLoader>
  30. #include <KMessageBox>
  31. namespace KMail
  32. {
  33. namespace MessageListView
  34. {
  35. namespace Core
  36. {
  37. class ThemeListWidgetItem : public QListWidgetItem
  38. {
  39. private:
  40. Theme * mTheme;
  41. public:
  42. ThemeListWidgetItem( QListWidget * par, const Theme &set )
  43. : QListWidgetItem( set.name(), par )
  44. {
  45. mTheme = new Theme( set );
  46. }
  47. ~ThemeListWidgetItem()
  48. {
  49. delete mTheme;
  50. }
  51. public:
  52. Theme * theme() const
  53. { return mTheme; };
  54. void forgetTheme()
  55. { mTheme = 0; };
  56. };
  57. ConfigureThemesDialog * ConfigureThemesDialog::mInstance = 0;
  58. ConfigureThemesDialog::ConfigureThemesDialog( QWidget *parent )
  59. : KDialog( parent )
  60. {
  61. mInstance = this;
  62. setAttribute( Qt::WA_DeleteOnClose );
  63. setWindowModality( Qt::ApplicationModal ); // FIXME: Sure ?
  64. setButtons( Ok | Cancel );
  65. setWindowTitle( i18n( "Customize Themes" ) );
  66. QWidget * base = new QWidget( this );
  67. setMainWidget( base );
  68. QGridLayout * g = new QGridLayout( base );
  69. mThemeList = new ThemeListWidget( base );
  70. mThemeList->setSortingEnabled( true );
  71. g->addWidget( mThemeList, 0, 0, 5, 1 );
  72. connect( mThemeList, SIGNAL( currentItemChanged( QListWidgetItem *, QListWidgetItem * ) ),
  73. SLOT( themeListCurrentItemChanged( QListWidgetItem *, QListWidgetItem * ) ) );
  74. mNewThemeButton = new QPushButton( i18n( "New Theme" ), base );
  75. mNewThemeButton->setIcon( KIcon( "document-new" ) );
  76. mNewThemeButton->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
  77. g->addWidget( mNewThemeButton, 0, 1 );
  78. connect( mNewThemeButton, SIGNAL( clicked() ),
  79. SLOT( newThemeButtonClicked() ) );
  80. mCloneThemeButton = new QPushButton( i18n( "Clone Theme" ), base );
  81. mCloneThemeButton->setIcon( KIcon( "edit-copy" ) );
  82. mCloneThemeButton->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
  83. g->addWidget( mCloneThemeButton, 1, 1 );
  84. connect( mCloneThemeButton, SIGNAL( clicked() ),
  85. SLOT( cloneThemeButtonClicked() ) );
  86. QFrame * f = new QFrame( base );
  87. f->setFrameStyle( QFrame::Sunken | QFrame::HLine );
  88. f->setMinimumHeight( 24 );
  89. g->addWidget( f, 2, 1, Qt::AlignVCenter );
  90. mDeleteThemeButton = new QPushButton( i18n( "Delete Theme" ), base );
  91. mDeleteThemeButton->setIcon( KIcon( "edit-delete" ) );
  92. mDeleteThemeButton->setIconSize( QSize( KIconLoader::SizeSmall, KIconLoader::SizeSmall ) );
  93. g->addWidget( mDeleteThemeButton, 3, 1 );
  94. connect( mDeleteThemeButton, SIGNAL( clicked() ),
  95. SLOT( deleteThemeButtonClicked() ) );
  96. mEditor = new ThemeEditor( base );
  97. g->addWidget( mEditor, 5, 0, 1, 2 );
  98. connect( mEditor, SIGNAL( themeNameChanged() ),
  99. SLOT( editedThemeNameChanged() ) );
  100. g->setColumnStretch( 0, 1 );
  101. g->setRowStretch( 4, 1 );
  102. connect( this, SIGNAL( okClicked() ),
  103. SLOT( okButtonClicked() ) );
  104. fillThemeList();
  105. }
  106. ConfigureThemesDialog::~ConfigureThemesDialog()
  107. {
  108. mInstance = 0;
  109. }
  110. void ConfigureThemesDialog::display( QWidget *parent, const QString &preselectThemeId )
  111. {
  112. if ( mInstance )
  113. return; // FIXME: reparent if needed ?
  114. mInstance = new ConfigureThemesDialog( parent );
  115. mInstance->selectThemeById( preselectThemeId );
  116. mInstance->show();
  117. }
  118. void ConfigureThemesDialog::cleanup()
  119. {
  120. if ( !mInstance )
  121. return;
  122. delete mInstance;
  123. mInstance = 0;
  124. }
  125. void ConfigureThemesDialog::selectThemeById( const QString &themeId )
  126. {
  127. ThemeListWidgetItem * item = findThemeItemById( themeId );
  128. if ( !item )
  129. return;
  130. mThemeList->setCurrentItem( item );
  131. }
  132. void ConfigureThemesDialog::okButtonClicked()
  133. {
  134. commitEditor();
  135. Manager::instance()->removeAllThemes();
  136. int c = mThemeList->count();
  137. int i = 0;
  138. while ( i < c )
  139. {
  140. ThemeListWidgetItem * item = dynamic_cast< ThemeListWidgetItem * >( mThemeList->item( i ) );
  141. if ( item )
  142. {
  143. Manager::instance()->addTheme( item->theme() );
  144. item->forgetTheme();
  145. }
  146. i++;
  147. }
  148. Manager::instance()->themesConfigurationCompleted();
  149. close(); // this will delete too
  150. }
  151. void ConfigureThemesDialog::commitEditor()
  152. {
  153. Theme * editedTheme = mEditor->editedTheme();
  154. if ( !editedTheme )
  155. return;
  156. mEditor->commit();
  157. ThemeListWidgetItem * editedItem = findThemeItemByTheme( editedTheme );
  158. if ( editedItem )
  159. return;
  160. // We must reset the runtime column state as the columns might have
  161. // totally changed in the editor
  162. editedTheme->resetColumnState();
  163. QString goodName = uniqueNameForTheme( editedTheme->name(), editedTheme );
  164. editedTheme->setName( goodName );
  165. editedItem->setText( goodName );
  166. }
  167. void ConfigureThemesDialog::editedThemeNameChanged()
  168. {
  169. Theme * set = mEditor->editedTheme();
  170. if ( !set )
  171. return;
  172. ThemeListWidgetItem * it = findThemeItemByTheme( set );
  173. if ( !it )
  174. return;
  175. QString goodName = uniqueNameForTheme( set->name(), set );
  176. it->setText( goodName );
  177. }
  178. void ConfigureThemesDialog::fillThemeList()
  179. {
  180. const QHash< QString, Theme * > & sets = Manager::instance()->themes();
  181. for( QHash< QString, Theme * >::ConstIterator it = sets.begin(); it != sets.end(); ++it )
  182. (void)new ThemeListWidgetItem( mThemeList, *( *it ) );
  183. }
  184. void ConfigureThemesDialog::themeListCurrentItemChanged( QListWidgetItem * cur, QListWidgetItem * )
  185. {
  186. commitEditor();
  187. ThemeListWidgetItem * item = cur ? dynamic_cast< ThemeListWidgetItem * >( cur ) : 0;
  188. mDeleteThemeButton->setEnabled( item && ( mThemeList->count() > 1 ) );
  189. mCloneThemeButton->setEnabled( item );
  190. mEditor->editTheme( item ? item->theme() : 0 );
  191. if ( item && !item->isSelected() )
  192. item->setSelected( true ); // make sure it's true
  193. }
  194. ThemeListWidgetItem * ConfigureThemesDialog::findThemeItemById( const QString &themeId )
  195. {
  196. int c = mThemeList->count();
  197. int i = 0;
  198. while ( i < c )
  199. {
  200. ThemeListWidgetItem * item = dynamic_cast< ThemeListWidgetItem * >( mThemeList->item( i ) );
  201. if ( item )
  202. {
  203. if ( item->theme()->id() == themeId )
  204. return item;
  205. }
  206. i++;
  207. }
  208. return 0;
  209. }
  210. ThemeListWidgetItem * ConfigureThemesDialog::findThemeItemByName( const QString &name, Theme * skipTheme )
  211. {
  212. int c = mThemeList->count();
  213. int i = 0;
  214. while ( i < c )
  215. {
  216. ThemeListWidgetItem * item = dynamic_cast< ThemeListWidgetItem * >( mThemeList->item( i ) );
  217. if ( item )
  218. {
  219. if ( item->theme() != skipTheme )
  220. {
  221. if ( item->theme()->name() == name )
  222. return item;
  223. }
  224. }
  225. i++;
  226. }
  227. return 0;
  228. }
  229. ThemeListWidgetItem * ConfigureThemesDialog::findThemeItemByTheme( Theme * set )
  230. {
  231. int c = mThemeList->count();
  232. int i = 0;
  233. while ( i < c )
  234. {
  235. ThemeListWidgetItem * item = dynamic_cast< ThemeListWidgetItem * >( mThemeList->item( i ) );
  236. if ( item )
  237. {
  238. if ( item->theme() == set )
  239. return item;
  240. }
  241. i++;
  242. }
  243. return 0;
  244. }
  245. QString ConfigureThemesDialog::uniqueNameForTheme( QString baseName, Theme * skipTheme )
  246. {
  247. QString ret = baseName;
  248. if( ret.isEmpty() )
  249. ret = i18n( "Unnamed Theme" );
  250. int idx = 1;
  251. ThemeListWidgetItem * item = findThemeItemByName( ret, skipTheme );
  252. while ( item )
  253. {
  254. idx++;
  255. ret = QString("%1 %2").arg( baseName ).arg( idx );
  256. item = findThemeItemByName( ret, skipTheme );
  257. }
  258. return ret;
  259. }
  260. void ConfigureThemesDialog::newThemeButtonClicked()
  261. {
  262. Theme emptyTheme;
  263. emptyTheme.setName( uniqueNameForTheme( i18n( "New Theme" ) ) );
  264. Theme::Column * col = new Theme::Column();
  265. col->setLabel( i18n( "New Column" ) );
  266. col->setVisibleByDefault( true );
  267. col->addMessageRow( new Theme::Row() );
  268. col->addGroupHeaderRow( new Theme::Row() );
  269. emptyTheme.addColumn( col );
  270. ThemeListWidgetItem * item = new ThemeListWidgetItem( mThemeList, emptyTheme );
  271. mThemeList->setCurrentItem( item );
  272. }
  273. void ConfigureThemesDialog::cloneThemeButtonClicked()
  274. {
  275. ThemeListWidgetItem * item = dynamic_cast< ThemeListWidgetItem * >( mThemeList->currentItem() );
  276. if ( !item )
  277. return;
  278. Theme copyTheme( *( item->theme() ) );
  279. copyTheme.detach(); // detach shared data
  280. copyTheme.generateUniqueId(); // regenerate id so it becomes different
  281. copyTheme.setName( uniqueNameForTheme( item->theme()->name() ) );
  282. item = new ThemeListWidgetItem( mThemeList, copyTheme );
  283. mThemeList->setCurrentItem( item );
  284. }
  285. void ConfigureThemesDialog::deleteThemeButtonClicked()
  286. {
  287. ThemeListWidgetItem * item = dynamic_cast< ThemeListWidgetItem * >( mThemeList->currentItem() );
  288. if ( !item )
  289. return;
  290. if ( mThemeList->count() < 2 )
  291. return; // no way: desperately try to keep at least one option set alive :)
  292. mEditor->editTheme( 0 ); // forget it
  293. delete item; // this will trigger themeListCurrentItemChanged()
  294. }
  295. } // namespace Core
  296. } // namespace MessageListView
  297. } // namespace KMail