1 /***************************************************************************
2  *   Copyright (C) 2003 by Sébastien Laoût                                 *
3  *   slaout@linux62.org                                                    *
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                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 
21 #include "basketproperties.h"
22 
23 #include <QtCore/QStringList>
24 #include <QHBoxLayout>
25 #include <QVBoxLayout>
26 #include <QGridLayout>
27 #include <QtGui/QPixmap>
28 #include <QLabel>
29 #include <QRadioButton>
30 #include <QGroupBox>
31 #include <QButtonGroup>
32 #include <QStyle>
33 #include <QLineEdit>
34 #include <QLocale>
35 #include <QApplication>
36 #include <QDialogButtonBox>
37 #include <QPushButton>
38 #include <QVBoxLayout>
39 
40 #include <KComboBox>
41 #include <KIconLoader>
42 #include <KIconDialog>
43 #include <KShortcutWidget>
44 #include <KConfigGroup>
45 #include <KLocalizedString>
46 
47 #include "backgroundmanager.h"
48 #include "basketscene.h"
49 #include "gitwrapper.h"
50 #include "global.h"
51 #include "kcolorcombo2.h"
52 #include "variouswidgets.h"
53 
54 
55 
56 #include "ui_basketproperties.h"
57 
BasketPropertiesDialog(BasketScene * basket,QWidget * parent)58 BasketPropertiesDialog::BasketPropertiesDialog(BasketScene *basket, QWidget *parent)
59         : QDialog(parent)
60         , Ui::BasketPropertiesUi()
61         , m_basket(basket)
62 {
63     // Set up dialog options
64     setWindowTitle(i18n("Basket Properties"));
65     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel|QDialogButtonBox::Apply, this);
66     QWidget *mainWidget = new QWidget(this);
67     setupUi(mainWidget);
68     QVBoxLayout *mainLayout = new QVBoxLayout;
69     setLayout(mainLayout);
70     mainLayout->addWidget(mainWidget);
71     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
72     okButton->setDefault(true);
73     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
74     connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
75     connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
76     mainLayout->addWidget(buttonBox);
77     okButton->setDefault(true);
78     setObjectName("BasketProperties");
79     setModal(true);
80 
81     Ui::BasketPropertiesUi* propsUi = dynamic_cast<Ui::BasketPropertiesUi*>(this); // cast to remove name ambiguity
82     propsUi->icon->setIconType(KIconLoader::NoGroup, KIconLoader::Action);
83     propsUi->icon->setIconSize(16);
84     propsUi->icon->setIcon(m_basket->icon());
85 
86     int size = qMax(propsUi->icon->sizeHint().width(), propsUi->icon->sizeHint().height());
87     propsUi->icon->setFixedSize(size, size); // Make it square!
88     propsUi->icon->setToolTip(i18n("Icon"));
89     propsUi->name->setText(m_basket->basketName());
90     propsUi->name->setMinimumWidth(propsUi->name->fontMetrics().maxWidth()*20);
91     propsUi->name->setToolTip(i18n("Name"));
92 
93     // Appearance:
94     m_backgroundColor = new KColorCombo2(m_basket->backgroundColorSetting(), palette().color(QPalette::Base), appearanceGroup);
95     m_textColor       = new KColorCombo2(m_basket->textColorSetting(),       palette().color(QPalette::Text), appearanceGroup);
96 
97     bgColorLbl->setBuddy(m_backgroundColor);
98     txtColorLbl->setBuddy(m_textColor);
99 
100     appearanceLayout->addWidget(m_backgroundColor, 1, 2);
101     appearanceLayout->addWidget(m_textColor, 2, 2);
102 
103     setTabOrder(backgroundImage, m_backgroundColor);
104     setTabOrder(m_backgroundColor, m_textColor);
105     setTabOrder(m_textColor, columnForm);
106 
107     backgroundImage->addItem(i18n("(None)"));
108     m_backgroundImagesMap.insert(0, "");
109     backgroundImage->setIconSize(QSize(100, 75));
110     QStringList backgrounds = Global::backgroundManager->imageNames();
111     int index = 1;
112     for (QStringList::Iterator it = backgrounds.begin(); it != backgrounds.end(); ++it) {
113         QPixmap *preview = Global::backgroundManager->preview(*it);
114         if (preview) {
115             m_backgroundImagesMap.insert(index, *it);
116             backgroundImage->insertItem(index, *it);
117             backgroundImage->setItemData(index, *preview, Qt::DecorationRole);
118             if (m_basket->backgroundImageName() == *it)
119                 backgroundImage->setCurrentIndex(index);
120             index++;
121         }
122     }
123 //  m_backgroundImage->insertItem(i18n("Other..."), -1);
124     int BUTTON_MARGIN = qApp->style()->pixelMetric(QStyle::PM_ButtonMargin);
125     backgroundImage->setMaxVisibleItems(50/*75 * 6 / m_backgroundImage->sizeHint().height()*/);
126     backgroundImage->setMinimumHeight(75 + 2 * BUTTON_MARGIN);
127 
128     // Disposition:
129 
130     columnCount->setRange(1, 20);
131     columnCount->setValue(m_basket->columnsCount());
132     connect(columnCount, SIGNAL(valueChanged(int)), this, SLOT(selectColumnsLayout()));
133 
134     int height = qMax(mindMap->sizeHint().height(), columnCount->sizeHint().height()); // Make all radioButtons vertically equaly-spaced!
135     mindMap->setMinimumSize(mindMap->sizeHint().width(), height); // Because the m_columnCount can be heigher, and make radio1 and radio2 more spaced than radio2 and radio3.
136 
137     if (!m_basket->isFreeLayout())
138         columnForm->setChecked(true);
139     else if (m_basket->isMindMap())
140         mindMap->setChecked(true);
141     else
142         freeForm->setChecked(true);
143 
144     mindMap->hide();
145 
146     // Keyboard Shortcut:
147     QList<QKeySequence> shortcuts{m_basket->shortcut()};
148     shortcut->setShortcut(shortcuts);
149 
150     HelpLabel *helpLabel = new HelpLabel(i18n("Learn some tips..."), i18n(
151                                              "<p><strong>Easily Remember your Shortcuts</strong>:<br>"
152                                              "With the first option, giving the basket a shortcut of the form <strong>Alt+Letter</strong> will underline that letter in the basket tree.<br>"
153                                              "For instance, if you are assigning the shortcut <i>Alt+T</i> to a basket named <i>Tips</i>, the basket will be displayed as <i><u>T</u>ips</i> in the tree. "
154                                              "It helps you visualize the shortcuts to remember them more quickly.</p>"
155                                              "<p><strong>Local vs Global</strong>:<br>"
156                                              "The first option allows you to show the basket while the main window is active. "
157                                              "Global shortcuts are valid from anywhere, even if the window is hidden.</p>"
158                                              "<p><strong>Show vs Switch</strong>:<br>"
159                                              "The last option makes this basket the current one without opening the main window. "
160                                              "It is useful in addition to the configurable global shortcuts, eg. to paste the clipboard or the selection into the current basket from anywhere.</p>"), 0);
161 
162     shortcutLayout->addWidget(helpLabel);
163     connect(shortcut, SIGNAL(shortcutChanged(const QList<QKeySequence>&)), this, SLOT(capturedShortcut(const QList<QKeySequence>&)));
164 
165     setTabOrder(columnCount, shortcut);
166     setTabOrder(shortcut, helpLabel);
167     setTabOrder(helpLabel, showBasket);
168 
169     switch (m_basket->shortcutAction()) {
170         default:
171         case 0: showBasket->setChecked(true); break;
172         case 1: globalButton->setChecked(true); break;
173         case 2: switchButton->setChecked(true); break;
174     }
175 
176 
177     // Connect the Ok and Apply buttons to actually apply the changes
178     connect(okButton, SIGNAL(clicked()), SLOT(applyChanges()));
179     connect(buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), SLOT(applyChanges()));
180 }
181 
~BasketPropertiesDialog()182 BasketPropertiesDialog::~BasketPropertiesDialog()
183 {
184 }
185 
ensurePolished()186 void BasketPropertiesDialog::ensurePolished()
187 {
188     ensurePolished();
189     Ui::BasketPropertiesUi* propsUi = dynamic_cast<Ui::BasketPropertiesUi*>(this);
190     propsUi->name->setFocus();
191 }
192 
applyChanges()193 void BasketPropertiesDialog::applyChanges()
194 {
195     if (columnForm->isChecked()) {
196         m_basket->setDisposition(0, columnCount->value());
197     } else if (freeForm->isChecked()) {
198         m_basket->setDisposition(1, columnCount->value());
199     } else {
200         m_basket->setDisposition(2, columnCount->value());
201     }
202 
203     if (showBasket->isChecked()) {
204         m_basket->setShortcut(shortcut->shortcut()[0], 0);
205     } else if (globalButton->isChecked()) {
206         m_basket->setShortcut(shortcut->shortcut()[0], 1);
207     } else if (switchButton->isChecked()) {
208         m_basket->setShortcut(shortcut->shortcut()[0], 2);
209     }
210 
211     Ui::BasketPropertiesUi* propsUi = dynamic_cast<Ui::BasketPropertiesUi*>(this);
212     // Should be called LAST, because it will emit the propertiesChanged() signal and the tree will be able to show the newly set Alt+Letter shortcut:
213     m_basket->setAppearance(propsUi->icon->icon(), propsUi->name->text(), m_backgroundImagesMap[backgroundImage->currentIndex()], m_backgroundColor->color(), m_textColor->color());
214     GitWrapper::commitBasket(m_basket);
215     m_basket->save();
216 }
217 
capturedShortcut(const QList<QKeySequence> & sc)218 void BasketPropertiesDialog::capturedShortcut(const QList<QKeySequence>& sc)
219 {
220     // TODO: Validate it!
221     shortcut->setShortcut(sc);
222 }
223 
selectColumnsLayout()224 void BasketPropertiesDialog::selectColumnsLayout()
225 {
226     columnForm->setChecked(true);
227 }
228 
229